]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/commitdiff
UserData cote botmodule to handle user data storage/retrieval
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>
Sun, 23 Sep 2007 10:57:08 +0000 (10:57 +0000)
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>
Sun, 23 Sep 2007 10:57:08 +0000 (10:57 +0000)
lib/rbot/botuser.rb
lib/rbot/core/userdata.rb [new file with mode: 0644]

index d61926b81906607e3b0b2fb5f607568f1fa9366a..a710a86375d65395accbab83bb51baaa271cc721 100644 (file)
@@ -237,9 +237,6 @@ class Bot
       attr_reader :password\r
       attr_reader :netmasks\r
       attr_reader :perm\r
-      # Please remember to #set_changed() the Auth.manager\r
-      # when modifying data\r
-      attr_reader :data\r
       attr_writer :login_by_mask\r
       attr_writer :transient\r
 \r
@@ -317,9 +314,6 @@ class Bot
         raise "must provide a usable mask for transient BotUser #{@username}" if @transient and @netmasks.empty?\r
 \r
         @perm = {}\r
-\r
-        # @data = AuthNotifyingHash.new\r
-        @data = {}\r
       end\r
 \r
       # Inspection\r
@@ -332,11 +326,6 @@ class Bot
         str << " @perm=#{@perm.inspect}"\r
         str << " @login_by_mask=#{@login_by_mask}"\r
         str << " @autologin=#{@autologin}"\r
-        if @data.empty?\r
-          str << " no data"\r
-        else\r
-          str << " data for #{@data.keys.join(', ')}"\r
-        end\r
         str << ">"\r
       end\r
 \r
@@ -354,7 +343,6 @@ class Bot
           :perm => @perm,\r
           :login_by_mask => @login_by_mask,\r
           :autologin => @autologin,\r
-          :data => @data\r
         }\r
       end\r
 \r
@@ -393,7 +381,6 @@ class Bot
           @netmasks.each { |n| Auth.manager.maskdb.add(self, n) } if @autologin\r
         end\r
         @perm = h[:perm] if h.has_key?(:perm)\r
-        @data.replace(h[:data]) if h.has_key?(:data)\r
       end\r
 \r
       # This method sets the password if the proposed new password\r
@@ -904,44 +891,6 @@ end
     def botuser\r
       Irc::Bot::Auth.manager.irc_to_botuser(self)\r
     end\r
-\r
-    # Bot-specific data can be stored with Irc::Users. This is\r
-    # internally obtained by storing data to the associated BotUser,\r
-    # but this is a detail plugin writers shouldn't care about.\r
-    # bot_data(:key) can be used to retrieve a particular data set.\r
-    # This method is intended for data retrieval, and if the retrieved\r
-    # data is modified directly there is no guarantee the changes will\r
-    # be saved back. Use #set_bot_data() for that.\r
-    #\r
-    def bot_data(key=nil)\r
-      return self.botuser.data if key.nil?\r
-      return self.botuser.data[key]\r
-    end\r
-\r
-    # This method is used to store bot-specific data for the receiver.\r
-    # If no block is passed, _value_ is stored for the key _key_;\r
-    # if a block is passed, it will be called with the previous\r
-    # _key_ value as parameter, and its return value will be stored\r
-    # as the new value. If _value_ is present in the block form, it\r
-    # will be used to initialize _key_ if it's missing\r
-    # \r
-    def set_bot_data(key,value=nil,&block)\r
-      if not block_given?\r
-        self.botuser.data[key]=value\r
-        Irc::Bot::Auth.manager.set_changed\r
-        return value\r
-      end\r
-      if value and not bot_data.has_key?(key)\r
-        set_bot_data(key, value)\r
-      end\r
-      r = value\r
-      begin\r
-        r = yield bot_data(key)\r
-      ensure\r
-        Irc::Bot::Auth.manager.set_changed\r
-      end\r
-      return r\r
-    end\r
   end\r
 \r
 end\r
diff --git a/lib/rbot/core/userdata.rb b/lib/rbot/core/userdata.rb
new file mode 100644 (file)
index 0000000..84524c0
--- /dev/null
@@ -0,0 +1,130 @@
+#-- vim:sw=2:et
+#++
+#
+# :title: rbot user data management from IRC
+#
+# Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
+# Copyright:: (C) 2006,2007 Giuseppe Bilotta
+# License:: GPL v2
+
+module ::Irc
+  class User
+    # Retrive Bot data associated with the receiver. This method is
+    # intended for data retrieval only. See #set_bot_data() if you
+    # need to alter User data.
+    #
+    def bot_data(key=nil)
+      Irc::Utils.bot.plugins['userdata'].get_data(self,key)
+    end
+
+    # This method is used to store Bot data associated with the
+    # receiver. If no block is passed, _value_ is stored for the key
+    # _key_; if a block is passed, it will be called with the previous
+    # _key_ value as parameter, and its return value will be stored as
+    # the new value. If _value_ is present in the block form, it will
+    # be used to initialize _key_ if it's missing
+    # 
+    def set_bot_data(key, value=nil, &block)
+      Irc::Utils.bot.plugins['userdata'].set_data(self, key, value, &block)
+    end
+  end
+end
+
+# User data is stored in registries indexed by BotUser
+# name and Irc::User nick. This core module takes care
+# of handling its usage.
+#
+class UserDataModule < CoreBotModule
+
+  def initialize
+    super
+    @ircuser = @registry.sub_registry('ircuser')
+    @botuser = @registry.sub_registry('botuser')
+  end
+
+  def get_data_hash(user)
+    iu = user.to_irc_user
+    bu = iu.botuser
+
+    ih = @ircuser[iu.nick] || {}
+
+    if bu.transient? or bu == Irc::Bot::Auth.defaultbotuser
+      return ih
+    else
+      bh = @botuser[bu.username] || {}
+      return ih.merge! bh
+    end
+  end
+
+  def get_data(user, key=nil)
+    h = get_data_hash(user)
+    debug h
+    return h if key.nil?
+    return h[key]
+  end
+
+  def set_data(user, key, value=nil, &block)
+    h = get_data_hash(user)
+    debug h
+
+    ret = value
+
+    if not block_given?
+      h[key] = value
+    else
+      if value and not h.has_key?(key)
+        h[key] = value
+      end
+      ret = yield h[key]
+    end
+    debug ret
+
+    iu = user.to_irc_user
+    bu = iu.botuser
+
+    if bu.transient? or bu == Irc::Bot::Auth.defaultbotuser
+      @ircuser[iu.nick] = h
+    else
+      @botuser[bu.username] = h
+    end
+    return ret
+  end
+
+  def handle_get(m, params)
+    user = m.server.get_user(params[:nick]) || m.source
+    key = params[:key].intern
+    data = get_data(user, key)
+    if data
+      m.reply (_("%{key} data for %{user}: %{data}") % {
+        :key => key,
+        :user => user.nick,
+        :data => data
+      })
+    else
+      m.reply (_("sorry, no %{key} data for %{user}") % {
+        :key => key,
+        :user => user.nick,
+      })
+    end
+  end
+
+  ### TODO FIXME not yet: are we going to allow non-string
+  ### values for data? if so, this can't work ...
+  #
+  # def handle_set(m, params)
+  #   user = m.server.get_user(params[:nick]) || m.source
+  #   key = params[:key].intern
+  #   data = params[:data].to_s
+  # end
+
+end
+
+plugin = UserDataModule.new
+
+plugin.map "get [:nick's] :key [data]",   :action => 'handle_get'
+plugin.map "get :key [data] [for :nick]", :action => 'handle_get'
+plugin.map "get :key [data] [of :nick]",  :action => 'handle_get'
+
+# plugin.map "set [:nick's] :key [data] to :data", :action => handle_get
+# plugin.map "set :key [data] [for :nick] to :data", :action => handle_get
+# plugin.map "set :key [data] [of :nick] to :data", :action => handle_get