2009-04-17 21:54:11 +00:00
|
|
|
"""
|
|
|
|
log.py: written by Scaevolus 2009
|
|
|
|
"""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import thread
|
|
|
|
import codecs
|
|
|
|
import time
|
2009-04-29 03:29:27 +00:00
|
|
|
import re
|
2009-04-17 21:54:11 +00:00
|
|
|
|
2009-07-08 17:04:30 +00:00
|
|
|
from util import hook
|
|
|
|
|
2009-04-17 21:54:11 +00:00
|
|
|
|
|
|
|
lock = thread.allocate_lock()
|
|
|
|
log_fds = {} # '%(net)s %(chan)s' : (filename, fd)
|
|
|
|
|
|
|
|
timestamp_format = '%H:%M:%S'
|
|
|
|
|
2009-04-18 03:51:14 +00:00
|
|
|
formats = {'PRIVMSG': '<%(nick)s> %(msg)s',
|
|
|
|
'PART': '-!- %(nick)s [%(user)s@%(host)s] has left %(chan)s',
|
2009-11-19 01:42:37 +00:00
|
|
|
'JOIN': '-!- %(nick)s [%(user)s@%(host)s] has joined %(param0)s',
|
2009-04-18 03:51:14 +00:00
|
|
|
'MODE': '-!- mode/%(chan)s [%(param_tail)s] by %(nick)s',
|
|
|
|
'KICK': '-!- %(param1)s was kicked from %(chan)s by %(nick)s [%(msg)s]',
|
2009-04-19 11:18:27 +00:00
|
|
|
'TOPIC': '-!- %(nick)s changed the topic of %(chan)s to: %(msg)s',
|
2009-11-18 03:29:00 +00:00
|
|
|
'QUIT': '-!- %(nick)s has quit [%(msg)s]',
|
|
|
|
'PING': '',
|
|
|
|
'NOTICE': ''
|
2009-07-08 17:28:15 +00:00
|
|
|
}
|
2009-04-18 03:51:14 +00:00
|
|
|
|
|
|
|
ctcp_formats = {'ACTION': '* %(nick)s %(ctcpmsg)s'}
|
2009-04-18 00:57:18 +00:00
|
|
|
|
2009-04-29 03:29:27 +00:00
|
|
|
irc_color_re = re.compile(r'(\x03(\d+,\d+|\d)|[\x0f\x02\x16\x1f])')
|
|
|
|
|
2009-04-19 11:18:27 +00:00
|
|
|
|
2009-11-18 00:19:26 +00:00
|
|
|
def get_log_filename(dir, server, chan):
|
|
|
|
return os.path.join(dir, 'log', gmtime('%Y'), server,
|
2009-04-18 00:13:54 +00:00
|
|
|
gmtime('%%s.%m-%d.log') % chan).lower()
|
2009-04-17 21:54:11 +00:00
|
|
|
|
2009-04-18 00:57:18 +00:00
|
|
|
|
2009-04-17 21:54:11 +00:00
|
|
|
def gmtime(format):
|
|
|
|
return time.strftime(format, time.gmtime())
|
|
|
|
|
2009-04-18 00:57:18 +00:00
|
|
|
|
2009-04-18 03:51:14 +00:00
|
|
|
def beautify(input):
|
|
|
|
format = formats.get(input.command, '%(raw)s')
|
|
|
|
args = vars(input)
|
|
|
|
leng = len(args['paraml'])
|
|
|
|
for n, p in enumerate(args['paraml']):
|
|
|
|
args['param' + str(n)] = p
|
|
|
|
args['param_' + str(abs(n - leng))] = p
|
|
|
|
|
|
|
|
args['param_tail'] = ' '.join(args['paraml'][1:])
|
2009-04-29 03:29:27 +00:00
|
|
|
args['msg'] = irc_color_re.sub('', args['msg'])
|
2009-07-08 17:28:15 +00:00
|
|
|
|
2009-04-18 03:51:14 +00:00
|
|
|
if input.command == 'PRIVMSG' and input.msg.count('\x01') >= 2:
|
|
|
|
#ctcp
|
|
|
|
ctcp = input.msg.split('\x01', 2)[1].split(' ', 1)
|
|
|
|
if len(ctcp) == 1:
|
|
|
|
ctcp += ['']
|
|
|
|
args['ctcpcmd'], args['ctcpmsg'] = ctcp
|
|
|
|
format = ctcp_formats.get(args['ctcpcmd'],
|
|
|
|
'%(nick)s [%(user)s@%(host)s] requested unknown CTCP '
|
|
|
|
'%(ctcpcmd)s from %(chan)s: %(ctcpmsg)s')
|
|
|
|
|
|
|
|
return format % args
|
|
|
|
|
|
|
|
|
2009-11-18 00:19:26 +00:00
|
|
|
def get_log_fd(dir, server, chan):
|
|
|
|
fn = get_log_filename(dir, server, chan)
|
|
|
|
cache_key = '%s %s' % (server, chan)
|
2009-04-17 21:54:11 +00:00
|
|
|
filename, fd = log_fds.get(cache_key, ('', 0))
|
|
|
|
|
|
|
|
if fn != filename: # we need to open a file for writing
|
|
|
|
if fd != 0: # is a valid fd
|
|
|
|
fd.flush()
|
|
|
|
fd.close()
|
|
|
|
dir = os.path.split(fn)[0]
|
|
|
|
if not os.path.exists(dir):
|
|
|
|
os.makedirs(dir)
|
2009-04-18 00:13:54 +00:00
|
|
|
fd = codecs.open(fn, 'a', 'utf-8')
|
2009-04-17 21:54:11 +00:00
|
|
|
log_fds[cache_key] = (fn, fd)
|
|
|
|
|
|
|
|
return fd
|
|
|
|
|
2009-04-18 00:57:18 +00:00
|
|
|
|
2009-11-19 00:39:27 +00:00
|
|
|
@hook.tee
|
2009-04-17 21:54:11 +00:00
|
|
|
def log(bot, input):
|
2009-04-18 00:57:18 +00:00
|
|
|
with lock:
|
2009-04-18 03:51:14 +00:00
|
|
|
timestamp = gmtime(timestamp_format)
|
2009-07-08 17:28:15 +00:00
|
|
|
|
2009-11-19 00:39:27 +00:00
|
|
|
fd = get_log_fd(bot.persist_dir, input.server, 'raw')
|
2009-04-18 03:51:14 +00:00
|
|
|
fd.write(timestamp + ' ' + input.raw + '\n')
|
2009-04-17 21:54:11 +00:00
|
|
|
|
2009-04-25 19:33:49 +00:00
|
|
|
if input.command == 'QUIT': # these are temporary fixes until proper
|
|
|
|
input.chan = 'quit' # presence tracking is implemented
|
|
|
|
if input.command == 'NICK':
|
2009-07-08 17:28:15 +00:00
|
|
|
input.chan = 'nick'
|
2009-04-19 11:18:27 +00:00
|
|
|
|
2009-04-23 02:49:06 +00:00
|
|
|
beau = beautify(input)
|
|
|
|
|
2009-11-18 03:29:00 +00:00
|
|
|
if beau == '': # don't log this
|
|
|
|
return
|
|
|
|
|
2009-04-17 21:54:11 +00:00
|
|
|
if input.chan:
|
2009-11-19 00:39:27 +00:00
|
|
|
fd = get_log_fd(bot.persist_dir, input.server, input.chan)
|
2009-04-23 02:49:06 +00:00
|
|
|
fd.write(timestamp + ' ' + beau + '\n')
|
2009-11-19 02:45:57 +00:00
|
|
|
|
2009-11-23 08:37:52 +00:00
|
|
|
print timestamp, input.chan, beau.encode('utf8', 'ignore')
|