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
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
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
:perm => @perm,\r
:login_by_mask => @login_by_mask,\r
:autologin => @autologin,\r
- :data => @data\r
}\r
end\r
\r
@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
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
--- /dev/null
+#-- 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