]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - lib/rbot/core/userdata.rb
+ WelcomeMessage class
[user/henk/code/ruby/rbot.git] / lib / rbot / core / userdata.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: rbot user data management from IRC
5 #
6 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
7 # Copyright:: (C) 2006,2007 Giuseppe Bilotta
8 # License:: GPL v2
9
10 module ::Irc
11   class User
12     # Retrive Bot data associated with the receiver. This method is
13     # intended for data retrieval only. See #set_bot_data() if you
14     # need to alter User data.
15     #
16     def botdata(key=nil)
17       Irc::Utils.bot.plugins['userdata'].get_data(self,key)
18     end
19     alias :get_botdata :botdata
20
21     # This method is used to store Bot data associated with the
22     # receiver. If no block is passed, _value_ is stored for the key
23     # _key_; if a block is passed, it will be called with the previous
24     # _key_ value as parameter, and its return value will be stored as
25     # the new value. If _value_ is present in the block form, it will
26     # be used to initialize _key_ if it's missing.
27     #
28     # If you have to do large-scale editing of the Bot data Hash,
29     # please use with_botdata.
30     # 
31     def set_botdata(key, value=nil, &block)
32       Irc::Utils.bot.plugins['userdata'].set_data(self, key, value, &block)
33     end
34
35     # This method yields the entire Bot data Hash to the block,
36     # and stores any changes done to it, returning a copy
37     # of the (changed) Hash.
38     #
39     def with_botdata(&block)
40       Irc::Utils.bot.plugins['userdata'].with_data(self, &block)
41     end
42
43   end
44 end
45
46 # User data is stored in registries indexed by BotUser
47 # name and Irc::User nick. This core module takes care
48 # of handling its usage.
49 #
50 class UserDataModule < CoreBotModule
51
52   def initialize
53     super
54     @ircuser = @registry.sub_registry('ircuser')
55     @transient = @registry.sub_registry('transient')
56     @botuser = @registry.sub_registry('botuser')
57   end
58
59   def get_data_hash(user, opts={})
60     plain = opts[:plain]
61     iu = user.to_irc_user
62     bu = iu.botuser
63
64     ih = @ircuser[iu.nick] || {}
65
66     if bu.default?
67       return ih
68     elsif bu.transient?
69       bh = @transient[bu.netmasks.first.fullform] || {}
70     else
71       bh = @botuser[bu.username] || {}
72     end
73     ih.merge!(bh)
74
75     unless plain
76       class << ih
77         alias :single_retrieve :[]
78         alias :single_assign :[]=
79           include DottedIndex
80       end
81     end
82
83     return ih
84   end
85
86   def get_data(user, key=nil)
87     h = get_data_hash(user)
88     debug h
89     return h if key.nil?
90     return h[key]
91   end
92
93   def set_data_hash(user, hh)
94     iu = user.to_irc_user
95     bu = iu.botuser
96
97     # we .dup the hash to remove singleton methods
98     # and make it dump-able
99     h = hh.dup
100
101     @ircuser[iu.nick] = h
102     return h if bu.default?
103
104     if bu.transient?
105       @transient[bu.netmasks.first.fullform] = h
106     else
107       @botuser[bu.username] = h
108     end
109     return h
110   end
111
112   def set_data(user, key, value=nil, &block)
113     h = get_data_hash(user)
114     debug h
115
116     ret = value
117
118     if not block_given?
119       h[key] = value
120     else
121       if value and not h.has_key?(key)
122         h[key] = value
123       end
124       ret = yield h[key]
125     end
126     debug ret
127
128     set_data_hash(user, h)
129
130     return ret
131   end
132
133   def with_data(user, &block)
134     h = get_data_hash(user)
135     debug h
136     yield h
137
138     set_data_hash(user, h)
139
140     return h
141   end
142
143   def handle_get(m, params)
144     user = m.server.get_user(params[:nick]) || m.source
145     key = params[:key].intern
146     data = get_data(user, key)
147     if data
148       m.reply(_("%{key} data for %{user}: %{data}") % {
149         :key => key,
150         :user => user.nick,
151         :data => data
152       })
153     else
154       m.reply(_("sorry, no %{key} data for %{user}") % {
155         :key => key,
156         :user => user.nick,
157       })
158     end
159   end
160
161   ### TODO FIXME not yet: are we going to allow non-string
162   ### values for data? if so, this can't work ...
163   #
164   # def handle_set(m, params)
165   #   user = m.server.get_user(params[:nick]) || m.source
166   #   key = params[:key].intern
167   #   data = params[:data].to_s
168   # end
169
170   def event_botuser(action, opts={})
171     case action
172     when :copy, :rename
173       source = opts[:source]
174       return unless @botuser.key?(source)
175       dest = opts[:dest]
176       @botuser[dest] = @botuser[source].dup
177       @botuser.delete(source) if action == :rename
178     when :pre_perm
179       @permification ||= {}
180       k = [opts[:irc_user], opts[:bot_user]]
181       @permification[k] = get_data_hash(opts[:irc_user], :plain => true)
182     when :post_perm
183       @permification ||= {}
184       k = [opts[:irc_user], opts[:bot_user]]
185       if @permification.has_key?(k)
186         @botuser[opts[:bot_user]] = @permification[k]
187         @permification.delete(k)
188       end
189     end
190   end
191
192 end
193
194 plugin = UserDataModule.new
195
196 plugin.map "get [:nick's] :key [data]",   :action => 'handle_get'
197 plugin.map "get :key [data] [for :nick]", :action => 'handle_get'
198 plugin.map "get :key [data] [of :nick]",  :action => 'handle_get'
199
200 # plugin.map "set [:nick's] :key [data] to :data", :action => handle_get
201 # plugin.map "set :key [data] [for :nick] to :data", :action => handle_get
202 # plugin.map "set :key [data] [of :nick] to :data", :action => handle_get