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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
# This Thaum remembers users' actions and is able to quote them.
# Go for it with `!seen <nick>`. You can even use wildcards with "*".
#
# The redis server version needs to be >= 1.3.10 for hash support.
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'rubygems'
require 'ponder'
require 'redis'
FORMAT = '%Y-%m-%d %H:%M:%S'
class String
def escape_redis
self.gsub(/([\|\[\]\?])/, '\\\\\1')
end
end
@redis = Redis.new(:thread_safe => true)
def remember(lowercase_nick, nick, user, host, channel, action,
action_content)
@redis.hmset(
lowercase_nick,
'nick', nick,
'user', user,
'host', host,
'channel', channel,
'action', action,
'action_content', action_content,
'updated_at', Time.now.to_i)
end
@ponder = Ponder::Thaum.new do |t|
t.server = 'chat.freenode.org'
t.port = 6667
t.nick = 'Ponder'
t.verbose = true
t.logging = false
end
@ponder.on :connect do
@ponder.join '#ponder'
end
@ponder.on :channel do |event_data|
remember(event_data[:nick].downcase, event_data[:nick], event_data[:user],
event_data[:host], event_data[:channel], event_data[:type],
event_data[:message])
end
@ponder.on [:join, :part, :quit] do |event_data|
remember(event_data[:nick].downcase, event_data[:nick], event_data[:user],
event_data[:host], event_data[:channel], event_data[:type],
(event_data[:message] || event_data[:channel]))
end
@ponder.on :nickchange do |event_data|
remember(event_data[:nick].downcase, event_data[:nick], event_data[:user],
event_data[:host], '', 'nickchange_old', event_data[:new_nick])
remember(event_data[:new_nick].downcase, event_data[:new_nick],
event_data[:user], event_data[:host], '', 'nickchange_new',
event_data[:nick])
end
@ponder.on :kick do |event_data|
remember(event_data[:nick].downcase, event_data[:nick], event_data[:user],
event_data[:host], event_data[:channel], 'kicker',
"#{event_data[:victim]} #{event_data[:reason]}")
remember(event_data[:victim].downcase, event_data[:victim],
'', '', event_data[:channel], 'victim',
"#{event_data[:nick]} #{event_data[:reason]}")
end
def last_seen(nick)
data = @redis.hgetall(nick)
case data['action']
when 'channel'
"#{data['nick']} wrote something in #{data['channel']} at #{Time.at(data['updated_at'].to_i).strftime(FORMAT)}."
when 'join'
"#{data['nick']} joined #{data['channel']} at #{Time.at(data['updated_at'].to_i).strftime(FORMAT)}."
when 'part'
"#{data['nick']} left #{data['channel']} at #{Time.at(data['updated_at'].to_i).strftime(FORMAT)} (#{data['action_content']})."
when 'quit'
"#{data['nick']} quit at #{Time.at(data['updated_at'].to_i).strftime(FORMAT)} (#{data['action_content']})."
when 'nickchange_old'
"#{data['nick']} renamed to #{data['action_content']}} at #{Time.at(data['updated_at'].to_i).strftime(FORMAT)}."
when 'nickchange_new'
"#{data['nick']} renamed to #{data['action_content']} at #{Time.at(data['updated_at'].to_i).strftime(FORMAT)}."
when 'kicker'
"#{data['nick']} kicked #{data['action_content'].split(' ')[0]} at #{Time.at(data['updated_at'].to_i).strftime(FORMAT)} from #{data['channel']} (#{data['action_content'].split(' ')[1]})."
when 'victim'
"#{data['nick']} was kicked by #{data['action_content'].split(' ')[0]} at #{Time.at(data['updated_at'].to_i).strftime(FORMAT)} from #{data['channel']} (#{data['action_content'].split(' ')[1]})."
end
end
@ponder.on :channel, /^!seen \S+$/ do |event_data|
nick = event_data[:message].split(' ')[1].downcase
# wildcards
if nick =~ /\*/
users = @redis.keys nick.escape_redis
results = users.length
case results
when 0
@ponder.message event_data[:channel], 'No such nick found.'
when 1
@ponder.message event_data[:channel], last_seen(users[0])
when 2..5
nicks = []
users.each do |user|
nicks << @redis.hgetall(user)['nick']
end
nicks = nicks.join(', ')
@ponder.message event_data[:channel], "#{results} nicks found (#{nicks})."
else
@ponder.message event_data[:channel], "Too many results (#{results})."
end
# single search
else
@ponder.whois(nick).callback do |result|
message = if @redis.exists nick
if result
"#{result[:nick]} is online. (#{last_seen(nick)})"
else
last_seen(nick)
end
else
if result
"#{result[:nick]} is online."
else
"#{nick} not found."
end
end
@ponder.message event_data[:channel], message
end
end
end
@ponder.connect
|