4 # :title: rbot IRC logging facilities
6 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
7 # Copyright:: (C) 2008 Giuseppe Bilotta
10 class IrcLogModule < CoreBotModule
12 Config.register Config::IntegerValue.new('irclog.max_open_files',
13 :default => 20, :validate => Proc.new { |v| v > 0 },
14 :desc => "Maximum number of irclog files to keep open at any one time.")
19 Dir.mkdir("#{@bot.botclass}/logs") unless File.exist?("#{@bot.botclass}/logs")
22 def logfile_close(where_str, reason = 'unknown reason')
23 f = @logs.delete(where_str) or return
24 stamp = Time.now.strftime '%Y/%m/%d %H:%M:%S'
25 f[1].puts "[#{stamp}] @ Log closed by #{@bot.myself.nick} (#{reason})"
29 # log IRC-related message +message+ to a file determined by +where+.
30 # +where+ can be a channel name, or a nick for private message logging
31 def irclog(message, where="server")
32 message = message.chomp
34 stamp = now.strftime("%Y/%m/%d %H:%M:%S")
35 if where.class <= Server
38 where_str = where.downcase.gsub(/[:!?$*()\/\\<>|"']/, "_")
40 unless @logs.has_key? where_str
41 if @logs.size > @bot.config['irclog.max_open_files']
42 @logs.keys.sort do |a, b|
43 @logs[a][0] <=> @logs[b][0]
44 end.slice(0, @logs.size - @bot.config['irclog.max_open_files']).each do |w|
45 logfile_close w, "idle since #{@logs[w][0]}"
48 f = File.new("#{@bot.botclass}/logs/#{where_str}", "a")
50 f.puts "[#{stamp}] @ Log started by #{@bot.myself.nick}"
51 @logs[where_str] = [now, f]
53 @logs[where_str][1].puts "[#{stamp}] #{message}"
54 @logs[where_str][0] = now
55 #debug "[#{stamp}] <#{where}> #{message}"
59 @logs.keys.each { |w| logfile_close(w, 'rescan or shutdown') }
65 irclog "-#{m.source}- #{m.message}", m.target
67 irclog "<#{m.source}> #{m.message}", m.target
70 irclog "@ quit (#{m.message})", ch
76 irclog "joined server #{m.server} as #{m.target}", "server"
82 method = 'log_message'
84 method = 'log_' + m.class.name.downcase.match(/^irc::(\w+)message$/).captures.first
86 if self.respond_to?(method)
87 self.__send__(method, m)
89 warning "unhandled logging for #{m.pretty_inspect} (no such method #{method})"
96 who = m.private? ? "me" : m.target
97 logtarget = m.private? ? m.source : m.target
101 irclog "* #{m.source} #{m.logmessage}", m.target
103 irclog "* #{m.source}(#{m.sourceaddress}) #{m.logmessage}", m.source
106 irclog "@ #{m.source} asked #{who} about version info", logtarget
108 irclog "@ #{m.source} asked #{who} about source info", logtarget
110 irclog "@ #{m.source} pinged #{who}", logtarget
112 irclog "@ #{m.source} asked #{who} what time it is", logtarget
114 irclog "@ #{m.source} asked #{who} about #{[m.ctcp, m.message].join(' ')}", logtarget
118 irclog "<#{m.source}> #{m.logmessage}", m.target
120 irclog "<#{m.source}(#{m.sourceaddress})> #{m.logmessage}", m.source
127 irclog "-#{m.source}(#{m.sourceaddress})- #{m.logmessage}", m.source
129 irclog "-#{m.source}- #{m.logmessage}", m.target
134 m.message.each_line { |line|
135 irclog "MOTD: #{line}", "server"
141 irclog "@ #{m.oldnick} is now known as #{m.newnick}", ch
147 irclog "@ Quit: #{m.source}: #{m.logmessage}", ch
152 irclog "@ Mode #{m.logmessage} by #{m.source}", m.target
157 debug "joined channel #{m.channel}"
158 irclog "@ Joined channel #{m.channel}", m.channel
160 irclog "@ #{m.source} joined channel #{m.channel}", m.channel
166 debug "left channel #{m.channel}"
167 irclog "@ Left channel #{m.channel} (#{m.logmessage})", m.channel
169 irclog "@ #{m.source} left channel #{m.channel} (#{m.logmessage})", m.channel
175 debug "kicked from channel #{m.channel}"
176 irclog "@ You have been kicked from #{m.channel} by #{m.source} (#{m.logmessage})", m.channel
178 irclog "@ #{m.target} has been kicked from #{m.channel} by #{m.source} (#{m.logmessage})", m.channel
189 if m.source == @bot.myself
190 irclog "@ I set topic \"#{m.topic}\"", m.channel
192 irclog "@ #{m.source} set topic \"#{m.topic}\"", m.channel
195 topic = m.channel.topic
196 irclog "@ Topic is \"#{m.topic}\"", m.channel
197 irclog "@ Topic set by #{topic.set_by} on #{topic.set_on}", m.channel
205 def unknown_message(m)
206 irclog m.logmessage, ".unknown"
210 ilm = IrcLogModule.new