6 # Keep a database of who last said/did what
8 define_structure :Saw, :nick, :time, :type, :where, :message
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)."))
15 def help(plugin, topic="")
16 _("seen <nick> => have you seen, or when did you last see <nick>")
20 unless(m.params =~ /^(\S)+$/)
21 m.reply "incorrect usage: " + help(m.plugin)
25 m.params.gsub!(/\?$/, "")
27 if @registry.has_key?(m.params)
28 m.reply seen(@registry[m.params])
30 rx = Regexp.new(m.params, true)
32 @registry.each {|nick, saw|
36 break if num_matched == @bot.config['seen.max_results']
40 m.reply _("nope!") if num_matched.zero?
45 return unless m.source
46 # keep database up to date with who last said what
51 type = m.action? ? 'ACTION' : 'PUBLIC'
52 store m, Saw.new(m.sourcenick.dup, now, type,
53 m.target.to_s, m.message.dup)
56 store m, Saw.new(m.sourcenick.dup, now, "QUIT",
60 store m, Saw.new(m.oldnick, now, "NICK", nil, m.newnick)
63 store m, Saw.new(m.sourcenick.dup, Time.new, "PART",
64 m.target.to_s, m.message.dup)
67 store m, Saw.new(m.sourcenick.dup, Time.new, "JOIN",
68 m.target.to_s, m.message.dup)
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)
79 reg # for backwards compatibility
89 :normal => _("%{nick} was last seen %{when}, %{doing}"),
90 :with_before => _("%{nick} was last seen %{when}, %{doing} and %{time} before %{did_before}")
93 if before && [:PART, :QUIT].include?(saw.type.to_sym) &&
94 [:PUBLIC, :ACTION].include?(before.type.to_sym)
95 did_before = case before.type.to_sym
97 _("saying \"%{message}\"")
99 _("doing *%{nick} %{message}*")
102 :message => before.message
105 format = :with_before
107 time_diff = saw.time - before.time
109 time_before = _("a moment")
110 elsif time_diff < 3600
111 time_before = _("a while")
120 ago = Time.new - saw.time
125 time = _("%{time} ago") % { :time => Utils.secs_to_string(ago) }
128 doing = case saw.type.to_sym
130 _("saying \"%{message}\"")
132 _("doing *%{message}*")
134 _("changing nick from %{nick} to %{message}")
136 if saw.message.empty?
137 _("leaving %{where}")
139 _("leaving %{where} (%{message})")
142 _("joining %{where}")
144 _("quitting IRC (%{message})")
146 _("changing the topic of %{where} to \"%{message}\"")
147 end % { :message => saw.message, :where => saw.where, :nick => saw.nick }
157 formats[:with_before] % {
161 :time => time_before,
162 :did_before => did_before
168 reg = @registry[saw.nick]
170 if reg && reg.is_a?(Array)
171 reg.shift if reg.size > 1
177 if m.is_a? NickMessage
178 @registry[m.newnick] = reg
181 @registry[saw.nick] = reg
184 plugin = SeenPlugin.new
185 plugin.register("seen")