summaryrefslogtreecommitdiff
path: root/lib/rbot/core/userdata.rb
blob: 85f386b28b008e8dd4a588b097a0006284790889 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#-- 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 botdata(key=nil)
      Irc::Utils.bot.plugins['userdata'].get_data(self,key)
    end
    alias :get_botdata :botdata

    # 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_botdata(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.default?
      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.default?
      @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