]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/seen.rb
multiple plugins: Changes to remove parenthesize warnings.
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / seen.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: Seen Plugin
5 #
6 # Keep a database of who last said/did what
7
8 define_structure :Saw, :nick, :time, :type, :where, :message
9
10 class SeenPlugin < Plugin
11   Config.register Config::IntegerValue.new('seen.max_results',
12     :default => 3, :validate => Proc.new{|v| v >= 0},
13     :desc => _("Maximum number of seen users to return in search (0 = no limit)."))
14
15   def help(plugin, topic="")
16     _("seen <nick> => have you seen, or when did you last see <nick>")
17   end
18
19   def privmsg(m)
20     unless(m.params =~ /^(\S)+$/)
21       m.reply "incorrect usage: " + help(m.plugin)
22       return
23     end
24
25     m.params.gsub!(/\?$/, "")
26
27     if @registry.has_key?(m.params)
28       m.reply seen(@registry[m.params])
29     else
30       rx = Regexp.new(m.params, true)
31       num_matched = 0
32       @registry.each {|nick, saw|
33         if nick.match(rx)
34           m.reply seen(saw)
35           num_matched += 1
36           break if num_matched == @bot.config['seen.max_results']
37         end
38       }
39
40       m.reply _("nope!") if num_matched.zero?
41     end
42   end
43
44   def listen(m)
45     return unless m.source
46     # keep database up to date with who last said what
47     now = Time.new
48     case m
49     when PrivMessage
50       return if m.private?
51       type = m.action? ? 'ACTION' : 'PUBLIC'
52       store m, Saw.new(m.sourcenick.dup, now, type,
53                        m.target.to_s, m.message.dup)
54     when QuitMessage
55       return if m.address?
56       store m, Saw.new(m.sourcenick.dup, now, "QUIT",
57                        nil, m.message.dup)
58     when NickMessage
59       return if m.address?
60       store m, Saw.new(m.oldnick, now, "NICK", nil, m.newnick)
61     when PartMessage
62       return if m.address?
63       store m, Saw.new(m.sourcenick.dup, Time.new, "PART",
64                        m.target.to_s, m.message.dup)
65     when JoinMessage
66       return if m.address?
67       store m, Saw.new(m.sourcenick.dup, Time.new, "JOIN",
68                        m.target.to_s, m.message.dup)
69     when TopicMessage
70       return if m.address? or m.info_or_set == :info
71       store m, Saw.new(m.sourcenick.dup, Time.new, "TOPIC",
72                        m.target.to_s, m.message.dup)
73     end
74   end
75
76   def seen(reg)
77     saw = case reg
78     when Struct::Saw
79       reg # for backwards compatibility
80     when Array
81       reg.last
82     end
83
84     before = reg.first
85
86     formats = {
87       :normal      => _("%{nick} was last seen %{when}, %{doing}"),
88       :with_before => _("%{nick} was last seen %{when}, %{doing} and %{time} before %{did_before}")
89     }
90
91     if [:PART, :QUIT].include?(saw.type.to_sym) &&
92        [:PUBLIC, :ACTION].include?(before.type.to_sym)
93       did_before = case before.type.to_sym
94       when :PUBLIC
95         _("saying \"%{message}\"")
96       when :ACTION
97         _("doing *%{nick} %{message}*")
98       end % {
99         :nick => saw.nick,
100         :message => before.message
101       }
102
103       format = :with_before
104
105       time_diff = saw.time - before.time
106       if time_diff < 300
107         time_before = _("a moment")
108       elsif time_diff < 3600
109         time_before = _("a while")
110       else
111         format = :normal
112       end
113     else
114       format = :normal
115     end
116
117     nick = saw.nick
118     ago = Time.new - saw.time
119
120     if (ago.to_i == 0)
121       time = _("just now")
122     else
123       time = _("%{time} ago") % { :time => Utils.secs_to_string(ago) }
124     end
125
126     doing = case saw.type.to_sym
127     when :PUBLIC
128       _("saying \"%{message}\"")
129     when :ACTION
130       _("doing *%{message}*")
131     when :NICK
132       _("changing nick from %{nick} to %{message}")
133     when :PART
134       if saw.message.empty?
135         _("leaving %{where}")
136       else
137         _("leaving %{where} (%{message})")
138       end
139     when :JOIN
140       _("joining %{where}")
141     when :QUIT
142       _("quitting IRC (%{message})")
143     when :TOPIC
144       _("changing the topic of %{where} to \"%{message}\"")
145     end % { :message => saw.message, :where => saw.where, :nick => saw.nick }
146
147     case format
148     when :normal
149       formats[:normal] % {
150         :nick  => saw.nick,
151         :when  => time,
152         :doing => doing,
153       }
154     when :with_before
155       formats[:with_before] % {
156         :nick  => saw.nick,
157         :when  => time,
158         :doing => doing,
159         :time  => time_before,
160         :did_before => did_before
161       }
162     end
163   end
164
165   def store(m, saw)
166     reg = @registry[saw.nick]
167
168     if reg && reg.is_a?(Array)
169       reg.shift if reg.size > 1
170       reg.push(saw)
171     else
172       reg = [saw]
173     end
174
175     if m.is_a? NickMessage
176       @registry[m.newnick] = reg
177     end
178
179     @registry[saw.nick] = reg
180   end
181 end
182 plugin = SeenPlugin.new
183 plugin.register("seen")