X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=data%2Frbot%2Fplugins%2Fseen.rb;h=529fdf8695f3d3125c858f13c6400e601040d3bb;hb=16336b4a240a4265d1f2df1e30d7b68d3a924287;hp=aec5a064fa8ebbd7c990119a71ad87a17ccbecb9;hpb=f358b3c1c6fad73b6de59085b6bf5e4a788233a2;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/data/rbot/plugins/seen.rb b/data/rbot/plugins/seen.rb index aec5a064..529fdf86 100644 --- a/data/rbot/plugins/seen.rb +++ b/data/rbot/plugins/seen.rb @@ -1,10 +1,21 @@ -Saw = Struct.new("Saw", :nick, :time, :type, :where, :message) +#-- vim:sw=2:et +#++ +# +# :title: Seen Plugin +# +# Keep a database of who last said/did what + +define_structure :Saw, :nick, :time, :type, :where, :message class SeenPlugin < Plugin + Config.register Config::IntegerValue.new('seen.max_results', + :default => 3, :validate => Proc.new{|v| v >= 0}, + :desc => "Maximum number of seen users to return in search (0 = no limit).") + def help(plugin, topic="") "seen => have you seen, or when did you last see " end - + def privmsg(m) unless(m.params =~ /^(\S)+$/) m.reply "incorrect usage: " + help(m.plugin) @@ -16,75 +27,133 @@ class SeenPlugin < Plugin if @registry.has_key?(m.params) m.reply seen(@registry[m.params]) else - m.reply "nope!" + rx = Regexp.new(m.params, true) + num_matched = 0 + @registry.each {|nick, saw| + if nick.match(rx) + m.reply seen(saw) + num_matched += 1 + break if num_matched == @bot.config['seen.max_results'] + end + } + + m.reply "nope!" if num_matched.zero? end end def listen(m) - return if m.sourcenick.nil? + return unless m.source # keep database up to date with who last said what - if m.kind_of?(PrivMessage) + now = Time.new + case m + when PrivMessage return if m.private? - if m.action? - @registry[m.sourcenick] = Saw.new(m.sourcenick.dup, Time.new, "ACTION", - m.target, m.message.dup) - else - @registry[m.sourcenick] = Saw.new(m.sourcenick.dup, Time.new, "PUBLIC", - m.target, m.message.dup) - end - elsif m.kind_of?(QuitMessage) - return if m.address? - @registry[m.sourcenick] = Saw.new(m.sourcenick.dup, Time.new, "QUIT", - nil, m.message.dup) - elsif m.kind_of?(NickMessage) + type = m.action? ? 'ACTION' : 'PUBLIC' + store m, Saw.new(m.sourcenick.dup, now, type, + m.target.to_s, m.message.dup) + when QuitMessage return if m.address? - @registry[m.message] = Saw.new(m.sourcenick.dup, Time.new, "NICK", - nil, m.message.dup) - @registry[m.sourcenick] = Saw.new(m.sourcenick.dup, Time.new, "NICK", - nil, m.message.dup) - elsif m.kind_of?(PartMessage) + store m, Saw.new(m.sourcenick.dup, now, "QUIT", + nil, m.message.dup) + when NickMessage return if m.address? - @registry[m.sourcenick] = Saw.new(m.sourcenick.dup, Time.new, "PART", - m.target, m.message.dup) - elsif m.kind_of?(JoinMessage) + store m, Saw.new(m.oldnick, now, "NICK", nil, m.newnick) + when PartMessage return if m.address? - @registry[m.sourcenick] = Saw.new(m.sourcenick.dup, Time.new, "JOIN", - m.target, m.message.dup) - elsif m.kind_of?(TopicMessage) + store m, Saw.new(m.sourcenick.dup, Time.new, "PART", + m.target.to_s, m.message.dup) + when JoinMessage return if m.address? - @registry[m.sourcenick] = Saw.new(m.sourcenick.dup, Time.new, "TOPIC", - m.target, m.message.dup) + store m, Saw.new(m.sourcenick.dup, Time.new, "JOIN", + m.target.to_s, m.message.dup) + when TopicMessage + return if m.address? or m.info_or_set == :info + store m, Saw.new(m.sourcenick.dup, Time.new, "TOPIC", + m.target.to_s, m.message.dup) end end - - def seen(saw) + + def seen(reg) + saw = case reg + when Struct::Saw + reg # for backwards compatibility + when Array + reg.last + end + ret = "#{saw.nick} was last seen " ago = Time.new - saw.time - + if (ago.to_i == 0) - ret += "just now, " + ret << "just now, " else - ret += Utils.secs_to_string(ago) + " ago, " + ret << Utils.secs_to_string(ago) + " ago, " end - case saw.type - when "PUBLIC" - ret += "saying #{saw.message}" - when "ACTION" - ret += "doing #{saw.nick} #{saw.message}" - when "NICK" - ret += "changing nick from #{saw.nick} to #{saw.message}" - when "PART" - ret += "leaving #{saw.where}" - when "JOIN" - ret += "joining #{saw.where}" - when "QUIT" - ret += "quitting IRC (#{saw.message})" - when "TOPIC" - ret += "changing the topic of #{saw.where} to #{saw.message}" + case saw.type.to_sym + when :PUBLIC + ret << "saying \"#{saw.message}\"" + when :ACTION + ret << "doing #{saw.nick} #{saw.message}" + when :NICK + ret << "changing nick from #{saw.nick} to #{saw.message}" + when :PART + ret << "leaving #{saw.where}" + ret << " (#{saw.message})" unless saw.message.empty? + when :JOIN + ret << "joining #{saw.where}" + when :QUIT + ret << "quitting IRC (#{saw.message})" + when :TOPIC + ret << "changing the topic of #{saw.where} to \"#{saw.message}\"" end + + case saw.type.to_sym + when :PART, :QUIT + before = reg.first + if before.type == "PUBLIC" || before.type == "ACTION" + time_diff = saw.time - before.time + if time_diff < 300 + time = "a moment" + elsif time_diff < 3600 + time = "a while" + else + return ret + end + + ret << ' and %{time} before' % { :time => time } + + if before.type == "PUBLIC" + ret << ' saying "%{message}"' % { + :message => before.message + } + elsif before.type == "ACTION" + ret << ' doing *%{message}*' % { + :nick => saw.nick, + :message => before.message + } + end + end + end + return ret + end + + def store(m, saw) + reg = @registry[saw.nick] + + if reg && reg.is_a?(Array) + reg.shift if reg.size > 1 + reg.push(saw) + else + reg = [saw] + end + + if m.is_a? NickMessage + @registry[m.newnick] = reg + end + + @registry[saw.nick] = reg end - end plugin = SeenPlugin.new plugin.register("seen")