]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/config.rb
Use symbols internally instead of strings for config keys.
[user/henk/code/ruby/rbot.git] / lib / rbot / config.rb
index 834b5a988dac35b899a52898f0a651a6da767049..e1a09c4a53589c155ceb91447486aba2ee068ae0 100644 (file)
@@ -3,6 +3,14 @@ module Irc
   require 'yaml'
   require 'rbot/messagemapper'
 
+  unless YAML.respond_to?(:load_file)
+      def YAML.load_file( filepath )
+        File.open( filepath ) do |f|
+          YAML::load( f )
+        end
+      end
+  end
+
   class BotConfigValue
     # allow the definition order to be preserved so that sorting by
     # definition order is possible. The BotConfigWizard does this to allow
@@ -15,12 +23,15 @@ module Irc
     attr_reader :requires_restart
     attr_reader :order
     def initialize(key, params)
-      unless key =~ /^.+\..+$/
+      # Keys must be in the form 'module.name'.
+      # They will be internally passed around as symbols,
+      # but we accept them both in string and symbol form.
+      unless key.to_s =~ /^.+\..+$/
         raise ArgumentError,"key must be of the form 'module.name'"
       end
       @order = @@order
       @@order += 1
-      @key = key
+      @key = key.intern
       if params.has_key? :default
         @default = params[:default]
       else
@@ -120,14 +131,21 @@ module Irc
       super
       @values = params[:values]
     end
+    def values
+      if @values.instance_of?(Proc)
+        return @values.call(BotConfig.bot)
+      else
+        return @values
+      end
+    end
     def parse(string)
-      unless @values.include?(string)
-        raise ArgumentError, "invalid value #{string}, allowed values are: " + @values.join(", ")
+      unless values.include?(string)
+        raise ArgumentError, "invalid value #{string}, allowed values are: " + values.join(", ")
       end
       string
     end
     def desc
-      "#{@desc} [valid values are: " + @values.join(", ") + "]"
+      "#{@desc} [valid values are: " + values.join(", ") + "]"
     end
   end
 
@@ -160,8 +178,17 @@ module Irc
     # supported via []
     def [](key)
       return @@items[key].value if @@items.has_key?(key)
+      return @@items[key.intern].value if @@items.has_key?(key.intern)
       # try to still support unregistered lookups
-      return @@config[key] if @@config.has_key?(key)
+      # but warn about them
+      if @@config.has_key?(key)
+        warning "Unregistered lookup #{key.inspect}"
+        return @@config[key]
+      end
+      if @@config.has_key?(key.intern)
+        warning "Unregistered lookup #{key.intern.inspect}"
+        return @@config[key.intern]
+      end
       return false
     end
 
@@ -189,7 +216,7 @@ module Irc
         end
       else
         @@items.each_key do |key|
-          name = key.split('.').first
+          name = key.to_s.split('.').first
           modules.push name unless modules.include?(name)
         end
         m.reply "modules: " + modules.join(", ")
@@ -197,7 +224,7 @@ module Irc
     end
 
     def handle_get(m, params)
-      key = params[:key]
+      key = params[:key].to_s.intern
       unless @@items.has_key?(key)
         m.reply "no such config key #{key}"
         return
@@ -207,7 +234,7 @@ module Irc
     end
 
     def handle_desc(m, params)
-      key = params[:key]
+      key = params[:key].to_s.intern
       unless @@items.has_key?(key)
         m.reply "no such config key #{key}"
       end
@@ -216,7 +243,7 @@ module Irc
     end
 
     def handle_unset(m, params)
-      key = params[:key]
+      key = params[:key].to_s.intern
       unless @@items.has_key?(key)
         m.reply "no such config key #{key}"
       end
@@ -225,7 +252,7 @@ module Irc
     end
 
     def handle_set(m, params)
-      key = params[:key]
+      key = params[:key].to_s.intern
       value = params[:value].to_s
       unless @@items.has_key?(key)
         m.reply "no such config key #{key}"
@@ -296,20 +323,40 @@ module Irc
                    :defaults => {:topic => false}
       
       if(File.exist?("#{@@bot.botclass}/conf.yaml"))
-        newconfig = YAML::load_file("#{@@bot.botclass}/conf.yaml")
-        @@config.update newconfig
-      else
-        # first-run wizard!
-        BotConfigWizard.new(@@bot).run
-        # save newly created config
-        save
+        begin
+          newconfig = YAML::load_file("#{@@bot.botclass}/conf.yaml")
+          newconfig.each { |key, val|
+            @@config[key.intern] = val
+          }
+          return
+        rescue
+          error "failed to read conf.yaml: #{$!}"
+        end
       end
+      # if we got here, we need to run the first-run wizard
+      BotConfigWizard.new(@@bot).run
+      # save newly created config
+      save
     end
 
-    # write current configuration to #{botclass}/conf.rbot
+    # write current configuration to #{botclass}/conf.yaml
     def save
-      File.open("#{@@bot.botclass}/conf.yaml", "w") do |file|
-        file.puts @@config.to_yaml
+      begin
+        debug "Writing new conf.yaml ..."
+        File.open("#{@@bot.botclass}/conf.yaml.new", "w") do |file|
+          savehash = {}
+          @@config.each { |key, val|
+            savehash[key.to_s] = val
+          }
+          file.puts savehash.to_yaml
+        end
+        debug "Officializing conf.yaml ..."
+        File.rename("#{@@bot.botclass}/conf.yaml.new",
+                    "#{@@bot.botclass}/conf.yaml")
+      rescue => e
+        error "failed to write configuration file conf.yaml! #{$!}"
+        error "#{e.class}: #{e}"
+        error e.backtrace.join("\n")
       end
     end
 
@@ -338,7 +385,7 @@ module Irc
       @questions.sort{|a,b| a.order <=> b.order }.each do |q|
         puts q.desc
         begin
-          print q.key + " [#{q.to_s}]: "
+          print q.key.to_s + " [#{q.to_s}]: "
           response = STDIN.gets
           response.chop!
           unless response.empty?