diff options
author | Brian Sherson <caretaker82@euclid.shersonb.net> | 2013-12-04 01:35:44 -0800 |
---|---|---|
committer | Brian Sherson <caretaker82@euclid.shersonb.net> | 2013-12-04 01:35:44 -0800 |
commit | 0d802dab5b586d511a6291248702c910502acaf7 (patch) | |
tree | f370db15b1a29c2fa8b6699188d28923b1361462 /logger.py | |
parent | 5cf8d2185f89aaf30e856bd0dbca88fbb51789ba (diff) |
Significant changes
Diffstat (limited to 'logger.py')
-rw-r--r-- | logger.py | 864 |
1 files changed, 542 insertions, 322 deletions
@@ -12,80 +12,75 @@ import traceback import Queue import ssl import urllib2 +import irc +modemapping = dict( + Y="ircop", q="owner", a="admin", o="op", h="halfop", v="voice") -class LogRotate(Thread): - def __init__(self, logger): - self.logger = logger - Thread.__init__(self) - self.daemon = True - self.start() - - def run(self): - Y, M, D, h, m, s, w, d, dst = time.localtime() - nextrotate = int(time.mktime((Y, M, D+1, 0, 0, 0, 0, 0, -1))) - #print time.time()-nextrotate - #print time.localtime(), time.localtime(nextrotate) - while True: - while nextrotate > time.time(): # May need to do this in a loop in case the following time.sleep command wakes up a second too early. - time.sleep(max(0.1, min((nextrotate-time.time(), 3600)))) - with self.logger.rotatelock: - if all([not log or log.closed for log in self.logger.consolelogs.values()+self.logger.channellogs.values()]): - ### If there are no logs to rotate, we are going to terminate this thread. Logger will spawn another LogRotate thread when needed. - self.logger.logrotate = None - break - now = time.localtime() - timestamp = reduce(lambda x, y: x+":"+y, [str(t) - .rjust(2, "0") for t in now[0:6]]) - for IRC in self.logger.labels.keys(): - if IRC.connected: - with IRC.lock: - try: - self.logger.rotateConsoleLog(IRC) - except: - with IRC.loglock: - exc, excmsg, tb = sys.exc_info() - print >>IRC.log, "%(timestamp)s !!! [LogRotate] Exception in module %(module)s" % vars() - for tbline in traceback.format_exc().split("\n"): - print >>IRC.log, "%(timestamp)s !!! [LogRotate] %(tbline)s" % vars() - IRC.log.flush() - if IRC.identity: - for channel in IRC.identity.channels: - try: - self.logger.rotateChannelLog(channel) - except: - with IRC.loglock: - exc, excmsg, tb = sys.exc_info() - print >>IRC.log, "%(timestamp)s !!! [LogRotate] Exception in module %(module)s" % vars() - for tbline in traceback.format_exc().split("\n"): - print >>IRC.log, "%(timestamp)s !!! [LogRotate] %(tbline)s" % vars() - IRC.log.flush() - nextrotate += 3600*24 - -class Logger(object): +class Logger(Thread): def __init__(self, logroot): self.logroot = logroot path = [logroot] - #print path + while not os.path.isdir(path[0]): split = os.path.split(path[0]) path.insert(1, split[1]) path[0] = split[0] - #print path + while len(path) > 1: path[0] = os.path.join(*path[:2]) del path[1] #print path os.mkdir(path[0]) - #return - self.consolelogs = {} - self.channellogs = {} + + self.logs = {} self.labels = {} self.rotatelock = Lock() - self.logrotate = None - def onModuleAdd(self, IRC, label): + Thread.__init__(self) + self.daemon = True + self.start() + + def run(self): + try: + Y, M, D, h, m, s, w, d, dst = time.localtime() + nextrotate = int(time.mktime((Y, M, D+1, 0, 0, 0, 0, 0, -1))) + while True: + while nextrotate > time.time(): # May need to do this in a loop in case the following time.sleep command wakes up a second too early. + time.sleep(max(0.1, min((nextrotate-time.time(), 3600)))) + with self.rotatelock: + if all([not log or log.closed for log in self.logs.values()]): + break + Y, M, D, h, m, s, w, d, dst = now = time.localtime() + for IRC in self.labels.keys(): + if IRC.connected: + with IRC.lock: + try: + self.rotateLog(IRC) + except: + exc, excmsg, tb = sys.exc_info() + IRC.logwrite(*["!!! [Logger] Exception in module %(module)s" % vars()]+["!!! [Logger] %s" % tbline for tbline in traceback.format_exc().split("\n")]) + if IRC.identity: + for channel in IRC.identity.channels: + try: + self.rotateLog(channel) + except: + exc, excmsg, tb = sys.exc_info() + IRC.logwrite(*["!!! [Logger] Exception in module %(module)s" % vars()]+["!!! [Logger] %s" % tbline for tbline in traceback.format_exc().split("\n")]) + for user in IRC.users: + if user in self.logs.keys(): + try: + self.closeLog(user) + except: + exc, excmsg, tb = sys.exc_info() + IRC.logwrite(*["!!! [Logger] Exception in module %(module)s" % vars()]+["!!! [Logger] %s" % tbline for tbline in traceback.format_exc().split("\n")]) + IRC.logopen(os.path.join(self.logroot, self.labels[IRC], "rawdata-%04d.%02d.%02d.log"%now[:3])) + nextrotate = int(time.mktime((Y, M, D+1, 0, 0, 0, 0, 0, -1))) + finally: + Thread.__init__(self) + + def onAddonAdd(self, IRC, label): if label in self.labels.values(): raise BaseException("Label already exists") if IRC in self.labels.keys(): @@ -94,289 +89,514 @@ class Logger(object): os.mkdir(os.path.join(self.logroot, label)) self.labels[IRC] = label if IRC.connected: - self.openConsoleLog(IRC) + self.openLog(IRC) if IRC.identity: for channel in IRC.identity.channels: - self.openChannelLog(channel) + self.openLog(channel) + now = time.localtime() + timestamp = reduce(lambda x, y: x+":"+y, [str(t).rjust(2, + "0") for t in now[0:6]]) + IRC.logopen(os.path.join(self.logroot, self.labels[IRC], + "rawdata-%04d.%02d.%02d.log"%now[:3])) - def onModuleRem(self, IRC): + def onAddonRem(self, IRC): if IRC.connected: - for channel in self.channellogs.keys(): + for channel in self.logs.keys(): if channel in IRC.channels: - if not self.channellogs[channel].closed: - self.closeChannelLog(channel) - del self.channellogs[channel] - if not self.consolelogs[IRC].closed: - self.closeConsoleLog(IRC) + if not self.logs[channel].closed: + self.closeLog(channel) + for user in self.logs.keys(): + if user in IRC.users: + if not self.logs[user].closed: + self.closeLog(user) + if not self.logs[IRC].closed: + self.closeLog(IRC) del self.labels[IRC] - del self.consolelogs[IRC] - def openConsoleLog(self, IRC): - with self.rotatelock: - if not self.logrotate or not self.logrotate.isAlive(): - self.logrotate = LogRotate(self) - now = time.localtime() - timestamp = reduce(lambda x, y: x+":"+y, [str(t).rjust(2, - "0") for t in now[0:6]]) - self.consolelogs[IRC] = open(os.path.join(self.logroot, self.labels[ - IRC], "console-%04d.%02d.%02d.log"%now[:3]), "a") - print >>self.consolelogs[IRC], "%s %s ### Log session started" % ( - timestamp, time.tzname[now[-1]]) - self.consolelogs[IRC].flush() - - def closeConsoleLog(self, IRC): - if IRC in self.consolelogs.keys() and type(self.consolelogs[IRC]) == file and not self.consolelogs[IRC].closed: - now = time.localtime() - timestamp = reduce(lambda x, y: x+":"+y, [str(t) - .rjust(2, "0") for t in now[0:6]]) - print >>self.consolelogs[IRC], "%s %s ### Log session ended" % ( - timestamp, time.tzname[now[-1]]) - self.consolelogs[IRC].close() - - def rotateConsoleLog(self, IRC): - self.closeConsoleLog(IRC) - self.openConsoleLog(IRC) - - def openChannelLog(self, channel): + def openLog(self, window): with self.rotatelock: - if not self.logrotate or not self.logrotate.isAlive(): - self.logrotate = LogRotate(self) - self.logrotate.daemon = True - self.logrotate.start() + if not self.isAlive(): + self.start() now = time.localtime() timestamp = reduce(lambda x, y: x+":"+y, [str(t).rjust(2, "0") for t in now[0:6]]) - label = self.labels[channel.context] - self.channellogs[channel] = open(os.path.join(self.logroot, label, "channel-%s-%04d.%02d.%02d.log"%((urllib2.quote(channel.name.lower()).replace("/", "%2f"),)+now[:3])), "a") - print >>self.channellogs[channel], "%s %s ### Log session started" % ( - timestamp, time.tzname[now[-1]]) - self.channellogs[channel].flush() - if channel.context.identity in channel.users: - if channel.topic: - print >>self.channellogs[channel], "%s %s <<< :%s 332 %s %s :%s" % (timestamp, time.tzname[now[-1]], channel.context.serv, channel.context.identity.nick, channel.name, channel.topic) - if channel.topicsetby and channel.topictime: - print >>self.channellogs[channel], "%s %s <<< :%s 333 %s %s %s %s" % (timestamp, time.tzname[now[-1]], channel.context.serv, channel.context.identity.nick, channel.name, channel.topicsetby, channel.topictime) - if channel.users: - secret = "s" in channel.modes.keys() and channel.modes["s"] - private = "p" in channel.modes.keys() and channel.modes["p"] - namesusers = [] - modes, symbols = channel.context.supports["PREFIX"] - print >>self.channellogs[channel], "%s %s <<< :%s 353 %s %s %s :%s" % (timestamp, time.tzname[now[-1]], - channel.context.serv, - channel.context.identity.nick, - "@" if secret else ("*" if private else "="), - channel.name, - " ".join(["".join([symbols[k] if modes[k] in channel.modes.keys() and user in channel.modes[modes[k]] else "" for k in xrange(len(modes))])+user.nick for user in channel.users])) - if channel.modes: - modes = channel.modes.keys() - modestr = "".join([mode for mode in modes if mode not in channel.context.supports["CHANMODES"][0]+channel.context.supports["PREFIX"][0] and channel.modes[mode]]) - params = " ".join([channel.modes[mode] for mode in modes if mode in channel.context.supports["CHANMODES"][1]+channel.context.supports["CHANMODES"][2] and channel.modes[mode]]) - print >>self.channellogs[channel], "%s %s <<< :%s 324 %s %s +%s %s" % (timestamp, time.tzname[now[-1]], channel.context.server, channel.context.identity.nick, channel.name, modestr, params) - if channel.created: - print >>self.channellogs[channel], "%s %s <<< :%s 329 %s %s %s" % (timestamp, time.tzname[now[-1]], channel.context.serv, channel.context.identity.nick, channel.name, channel.created) - self.channellogs[channel].flush() - - def closeChannelLog(self, channel): - if channel in self.channellogs.keys() and type(self.channellogs[channel]) == file and not self.channellogs[channel].closed: - now = time.localtime() - timestamp = reduce(lambda x, y: x+":"+y, [str(t) - .rjust(2, "0") for t in now[0:6]]) - print >>self.channellogs[channel], "%s %s ### Log session ended" % (timestamp, time.tzname[now[-1]]) - self.channellogs[channel].close() - - def rotateChannelLog(self, channel): - self.closeChannelLog(channel) - self.openChannelLog(channel) - - def onRecv(self, IRC, line, data): - modemapping = dict(Y="ircop", q="owner", a="admin", o="op", - h="halfop", v="voice") - now = time.localtime() - timestamp = reduce(lambda x, y: x+":"+y, [str(t).rjust(2, - "0") for t in now[0:6]]) - if data is None: - print >>self.consolelogs[IRC], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.consolelogs[IRC].flush() - return - (origin, ident, host, cmd, target, params, extinfo) = data - if re.match("^\\d+$", cmd): - cmd = int(cmd) - if cmd in (324, 329): - modeparams = params.split() - channame = modeparams[0] - channel = IRC.channel(channame) - if channel in self.channellogs.keys() and not self.channellogs[channel].closed: - log = self.channellogs[channel] + if type(window) == irc.Connection: + log = self.logs[window] = open(os.path.join(self.logroot, self.labels[window], "console-%04d.%02d.%02d.log"%now[:3]), "a") + print >>log, "%s ### Log file opened" % (irc.timestamp()) + elif type(window) == irc.Channel: + label = self.labels[window.context] + log = self.logs[window] = open(os.path.join(self.logroot, label, "channel-%s-%04d.%02d.%02d.log"%((urllib2.quote(window.name.lower()).replace("/", "%2f"),)+now[:3])), "a") + print >>log, "%s ### Log file opened" % (irc.timestamp()) + self.logs[window].flush() + if window.context.identity in window.users: + if window.topic: + print >>log, "%s <<< :%s 332 %s %s :%s" % (irc.timestamp(), window.context.serv, window.context.identity.nick, window.name, window.topic) + if window.topicsetby and window.topictime: + print >>log, "%s <<< :%s 333 %s %s %s %s" % (irc.timestamp(), window.context.serv, window.context.identity.nick, window.name, window.topicsetby, window.topictime) + if window.users: + secret = "s" in window.modes.keys() and window.modes["s"] + private = "p" in window.modes.keys() and window.modes["p"] + namesusers = [] + modes, symbols = window.context.supports["PREFIX"] + print >>log, "%s <<< :%s 353 %s %s %s :%s" % (irc.timestamp(), + window.context.serv, + window.context.identity.nick, + "@" if secret else ("*" if private else "="), + window.name, + " ".join(["".join([symbols[k] if modes[k] in window.modes.keys() and user in window.modes[modes[k]] else "" for k in xrange(len(modes))])+user.nick for user in window.users])) + if window.modes: + modes = window.modes.keys() + modestr = "".join([mode for mode in modes if mode not in window.context.supports["CHANMODES"][0]+window.context.supports["PREFIX"][0] and window.modes[mode]]) + params = " ".join([window.modes[mode] for mode in modes if mode in window.context.supports["CHANMODES"][1]+window.context.supports["CHANMODES"][2] and window.modes[mode]]) + print >>log, "%s <<< :%s 324 %s %s +%s %s" % (irc.timestamp(), window.context.serv, window.context.identity.nick, window.name, modestr, params) + if window.created: + print >>log, "%s <<< :%s 329 %s %s %s" % (irc.timestamp(), window.context.serv, window.context.identity.nick, window.name, window.created) + if type(window) == irc.User: + logname = os.path.join(self.logroot, self.labels[window.context], "query-%s-%04d.%02d.%02d.log"%((urllib2.quote(window.nick.lower()).replace("/", "%2f"),)+now[:3])) + for (other, log) in self.logs.items(): + if other == window: + continue + if log.name == logname: + print >>log, "%s ### Log file closed" % (irc.timestamp()) + del self.logs[other] + self.logs[window] = log + if window not in self.logs.keys(): + log = self.logs[window] = open(logname, "a") else: - log = self.consolelogs[IRC] - print >>log, "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - log.flush() - elif cmd == 332: - channel = IRC.channel(params) - if channel in self.channellogs.keys() and not self.channellogs[channel].closed: - log = self.channellogs[channel] + log = self.logs[window] + print >>log, "%s ### Log file opened" % (irc.timestamp()) + log.flush() + + def closeLog(self, window): + if window in self.logs.keys() and type(self.logs[window]) == file and not self.logs[window].closed: + print >>self.logs[window], "%s ### Log file closed" % ( + irc.timestamp()) + self.logs[window].close() + if window in self.logs.keys(): + del self.logs[window] + + def rotateLog(self, window): + self.closeLog(window) + self.openLog(window) + + def onConnectAttempt(self, IRC): + if IRC not in self.logs.keys() or (not self.logs[IRC]) or self.logs[IRC].closed: + self.openLog(IRC) + ts = irc.timestamp() + print >>self.logs[IRC], "%s *** Attempting connection to %s:%s." % ( + ts, IRC.server, IRC.port) + + def onConnect(self, IRC): + if IRC not in self.logs.keys() or (not self.logs[IRC]) or self.logs[IRC].closed: + self.openLog(IRC) + ts = irc.timestamp() + print >>self.logs[IRC], "%s *** Connection to %s:%s established." % ( + ts, IRC.server, IRC.port) + + def onConnectFail(self, IRC, exc, excmsg, tb): + ### Called when a connection attempt fails. + if IRC not in self.logs.keys() or (not self.logs[IRC]) or self.logs[IRC].closed: + self.openLog(IRC) + ts = irc.timestamp() + print >>self.logs[IRC], "%s *** Connection to %s:%s failed: %s." % ( + ts, IRC.server, IRC.port, excmsg) + + def onDisconnect(self, IRC, expected=False): + ts = irc.timestamp() + for window in self.logs.keys(): + if type(window) in (irc.Channel, irc.User) and window.context == IRC: + print >>self.logs[window], "%s *** Connection to %s:%s terminated." % (ts, IRC.server, IRC.port) + self.logs[window].flush() + self.closeLog(window) + print >>self.logs[IRC], "%s *** Connection %s:%s terminated." % ( + ts, IRC.server, IRC.port) + self.logs[IRC].flush() + self.closeLog(IRC) + + def onJoin(self, IRC, user, channel): + ### Called when somebody joins a channel, includes bot. + ts = irc.timestamp() + if user == IRC.identity: + self.openLog(channel) + print >>self.logs[channel], "%s <<< :%s!%s@%s JOIN %s" % ( + ts, user.nick, user.username, user.host, channel.name) + self.logs[channel].flush() + + def onChanMsg(self, IRC, user, channel, targetprefix, msg): + ### Called when someone sends a PRIVMSG to channel. + ts = irc.timestamp() + if type(user) == irc.User: + classes = " ".join([modemapping[mode] for mode in IRC.supports["PREFIX"][0] if mode in channel.modes.keys() and user in channel.modes[mode]]) + if classes: + print >>self.logs[channel], "%s %s <<< :%s!%s@%s PRIVMSG %s%s :%s" % (ts, classes, user.nick, user.username, user.host, targetprefix, channel.name, msg) else: - log = self.consolelogs[IRC] - print >>log, "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - log.flush() - elif cmd == 333: - (channame, nick, dt) = params.split() - channel = IRC.channel(channame) - if not self.channellogs[channel].closed: - print >>self.channellogs[channel], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() - elif cmd == 353: - (flag, channame) = params.split() - channel = IRC.channel(channame) - if not self.channellogs[channel].closed: - print >>self.channellogs[channel], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() - elif cmd == "JOIN": - user = IRC.user(origin) - channel = IRC.channel(target if len(target) else extinfo) - if user == IRC.identity: - self.openChannelLog(channel) - print >>self.channellogs[channel], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() - elif cmd == "PRIVMSG": - if target and target[0] in IRC.supports["CHANTYPES"]: - channel = IRC.channel(target) - if ident and host: - user = IRC.user(origin) - classes = " ".join([modemapping[mode] for mode in IRC.supports["PREFIX"][0] if mode in channel.modes.keys() and user in channel.modes[mode]]) - else: - classes = "server" - if classes: - print >>self.channellogs[channel], "%s %s %s <<< %s" % (timestamp, time.tzname[now[-1]], classes, line) - else: - print >>self.channellogs[channel], "%s %s <<< %s" % (timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() - elif cmd == "NOTICE": - if target and (target[0] in IRC.supports["CHANTYPES"] or (len(target) > 1 and target[0] in IRC.supports["PREFIX"][1] and target[1] in IRC.supports["CHANTYPES"])): - if target[0] in IRC.supports["PREFIX"][1]: - channel = IRC.channel(target[1:]) - else: - channel = IRC.channel(target) - if ident and host: - user = IRC.user(origin) - classes = " ".join([modemapping[mode] for mode in IRC.supports["PREFIX"][0] if mode in channel.modes.keys() and user in channel.modes[mode]]) - else: - classes = "server" - if classes: - print >>self.channellogs[channel], "%s %s %s <<< %s" % (timestamp, time.tzname[now[-1]], classes, line) - else: - print >>self.channellogs[channel], "%s %s <<< %s" % (timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() - elif target.lower() == IRC.identity.nick.lower() and not ident and not host: - print >>self.consolelogs[IRC], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.consolelogs[IRC].flush() - elif cmd == "TOPIC": - channel = IRC.channel(target) - print >>self.channellogs[channel], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() - elif cmd == "PART": - user = IRC.user(origin) - channel = IRC.channel(target) - print >>self.channellogs[channel], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() - if user == IRC.identity: - self.closeChannelLog(channel) - elif cmd == "KICK": - kicked = IRC.user(params) - channel = IRC.channel(target) - print >>self.channellogs[channel], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() - if kicked == IRC.identity: - self.closeChannelLog(channel) - elif cmd == "MODE": - if target and target[0] in IRC.supports["CHANTYPES"]: - channel = IRC.channel(target) - print >>self.channellogs[channel], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() + print >>self.logs[channel], "%s <<< :%s!%s@%s PRIVMSG %s%s :%s" % (ts, user.nick, user.username, user.host, targetprefix, channel.name, msg) + elif type(user) in (str, unicode): + classes = "server" + print >>self.logs[channel], "%s %s <<< :%s PRIVMSG %s%s :%s" % (ts, + classes, user, targetprefix, channel.name, msg) + self.logs[channel].flush() + + def onChanAction(self, IRC, user, channel, targetprefix, action): + self.onChanMsg(IRC, user, channel, targetprefix, + "\x01ACTION %s\x01"%action) + + def onChanNotice(self, IRC, origin, channel, targetprefix, msg): + ### Called when someone sends a NOTICE to channel. + ts = irc.timestamp() + if type(origin) == irc.User: + classes = " ".join([modemapping[mode] for mode in IRC.supports["PREFIX"][0] if mode in channel.modes.keys() and origin in channel.modes[mode]]) + if classes: + print >>self.logs[channel], "%s %s <<< :%s!%s@%s NOTICE %s%s :%s" % (ts, classes, origin.nick, origin.username, origin.host, targetprefix, channel.name, msg) else: - print >>self.consolelogs[IRC], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.consolelogs[IRC].flush() - elif cmd in ("NICK", "QUIT"): - user = IRC.user(origin) - for channel in user.channels: - print >>self.channellogs[channel], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.channellogs[channel].flush() + print >>self.logs[channel], "%s <<< :%s!%s@%s NOTICE %s%s :%s" % (ts, origin.nick, origin.username, origin.host, targetprefix, channel.name, msg) + elif type(origin) in (str, unicode): + classes = "server" + print >>self.logs[channel], "%s %s <<< :%s NOTICE %s%s :%s" % (ts, + classes, origin, targetprefix, channel.name, msg) + self.logs[channel].flush() + + def onPart(self, IRC, user, channel, partmsg): + ### Called when somebody parts the channel, includes bot. + ts = irc.timestamp() + if partmsg: + print >>self.logs[channel], "%s <<< :%s!%s@%s PART %s :%s" % (ts, user.nick, user.username, user.host, channel.name, partmsg) else: - print >>self.consolelogs[IRC], "%s %s <<< %s" % ( - timestamp, time.tzname[now[-1]], line) - self.consolelogs[IRC].flush() + print >>self.logs[channel], "%s <<< :%s!%s@%s PART %s" % (ts, + user.nick, user.username, user.host, channel.name) + self.logs[channel].flush() + if user == IRC.identity: + self.closeLog(channel) - def onConnectAttempt(self, IRC): - if IRC not in self.consolelogs.keys() or (not self.consolelogs[IRC]) or self.consolelogs[IRC].closed: - self.openConsoleLog(IRC) - now = time.localtime() - timestamp = reduce(lambda x, y: x+":"+y, [str(t).rjust(2, - "0") for t in now[0:6]]) - print >>self.consolelogs[IRC], "%s %s *** Attempting connection to %s:%s." % (timestamp, time.tzname[now[-1]], IRC.server, IRC.port) + def onKick(self, IRC, kicker, channel, kicked, kickmsg): + ### Called when somebody is kicked from the channel, includes bot. + ts = irc.timestamp() + if kickmsg: + print >>self.logs[channel], "%s <<< :%s!%s@%s KICK %s %s :%s" % (ts, kicker.nick, kicker.username, kicker.host, channel.name, kicked.nick, kickmsg) + else: + print >>self.logs[channel], "%s <<< :%s!%s@%s KICK %s %s" % (ts, user.nick, user.username, user.host, channel.name, kicked.nick) + self.logs[channel].flush() + if user == IRC.identity: + self.closeLog(channel) - def onConnect(self, IRC): - if IRC not in self.consolelogs.keys() or (not self.consolelogs[IRC]) or self.consolelogs[IRC].closed: - self.openConsoleLog(IRC) - #self.openConsoleLog(IRC) - now = time.localtime() - timestamp = reduce(lambda x, y: x+":"+y, [str(t).rjust(2, - "0") for t in now[0:6]]) - print >>self.consolelogs[IRC], "%s %s *** Connection to %s:%s established." % (timestamp, time.tzname[now[-1]], IRC.server, IRC.port) + def onSendChanMsg(self, IRC, origin, channel, targetprefix, msg): + ### Called when bot sends a PRIVMSG to channel. + ### The variable origin refers to a class instance voluntarily identifying itself as that which requested data be sent. + ts = irc.timestamp() + classes = " ".join([modemapping[mode] for mode in IRC.supports["PREFIX"][0] if mode in channel.modes.keys() and IRC.identity in channel.modes[mode]]) + if classes: + print >>self.logs[channel], "%s %s >>> :%s!%s@%s PRIVMSG %s%s :%s" % (ts, classes, IRC.identity.nick, IRC.identity.username, IRC.identity.host, targetprefix, channel.name, msg) + else: + print >>self.logs[channel], "%s >>> :%s!%s@%s PRIVMSG %s%s :%s" % (ts, IRC.identity.nick, IRC.identity.username, IRC.identity.host, targetprefix, channel.name, msg) + self.logs[channel].flush() - def onDisconnect(self, IRC): - now = time.localtime() - timestamp = reduce(lambda x, y: x+":"+y, [str(t).rjust(2, - "0") for t in now[0:6]]) - for channel in IRC.identity.channels: - print >>self.channellogs[channel], "%s %s *** Connection to %s:%s terminated." % (timestamp, time.tzname[now[-1]], IRC.server, IRC.port) - self.channellogs[channel].flush() - self.closeChannelLog(channel) - print >>self.consolelogs[IRC], "%s %s *** Connection %s:%s terminated." % (timestamp, time.tzname[now[-1]], IRC.server, IRC.port) - self.consolelogs[IRC].flush() - self.closeConsoleLog(IRC) - - def onSend(self, IRC, line, data, origin): - modemapping = dict(Y="ircop", q="owner", a="admin", o="op", - h="halfop", v="voice") - now = time.localtime() - timestamp = reduce(lambda x, y: x+":"+y, [str(t).rjust(2, - "0") for t in now[0:6]]) - (cmd, target, params, extinfo) = data - if IRC.registered and cmd == "PRIVMSG" and "CHANTYPES" in IRC.supports.keys() and len(target) and target[0] in IRC.supports["CHANTYPES"]: - channel = IRC.channel(target) - if channel in IRC.identity.channels: - classes = " ".join([modemapping[mode] for mode in IRC.supports["PREFIX"][0] if mode in channel.modes.keys() and IRC.identity in channel.modes[mode]]) - if classes: - print >>self.channellogs[channel], "%s %s %s >>> :%s!%s@%s %s" % (timestamp, time.tzname[now[-1]], classes, IRC.identity.nick, IRC.identity.idnt, IRC.identity.host, line) - else: - print >>self.channellogs[channel], "%s %s >>> :%s!%s@%s %s" % (timestamp, time.tzname[now[-1]], IRC.identity.nick, IRC.identity.idnt, IRC.identity.host, line) - self.channellogs[channel].flush() + def onSendChanAction(self, IRC, origin, channel, targetprefix, action): + ### origin is the source of the channel message + ### Called when bot sends an action (/me) to channel. + ### The variable origin refers to a class instance voluntarily identifying itself as that which requested data be sent. + self.onSendChanMsg(IRC, origin, channel, targetprefix, + "\x01ACTION %s\x01"%action) + + def onPrivMsg(self, IRC, user, msg): + ### Called when someone sends a PRIVMSG to the bot. + if user not in self.logs.keys(): + self.openLog(user) + ts = irc.timestamp() + print >>self.logs[user], "%s <<< :%s!%s@%s PRIVMSG %s :%s" % (ts, user.nick, user.username, user.host, IRC.identity.nick, msg) + self.logs[user].flush() + + def onPrivNotice(self, IRC, origin, msg): + ### Called when someone sends a NOTICE to the bot. + ts = irc.timestamp() + if type(origin) == irc.User: + if origin not in self.logs.keys(): + self.openLog(origin) + print >>self.logs[origin], "%s <<< :%s!%s@%s NOTICE %s :%s" % (ts, origin.nick, origin.username, origin.host, IRC.identity.nick, msg) + self.logs[origin].flush() + else: + print >>self.logs[IRC], "%s <<< :%s NOTICE %s :%s" % ( + ts, origin, IRC.identity.nick, msg) + self.logs[IRC].flush() + + def onPrivAction(self, IRC, user, action): + ### Called when someone sends an action (/me) to the bot. + self.onPrivMsg(IRC, user, "\x01ACTION %s\x01"%action) + + def onSendPrivMsg(self, IRC, origin, user, msg): + ### Called when bot sends a PRIVMSG to a user. + ### The variable origin refers to a class instance voluntarily identifying itself as that which requested data be sent. + if user not in self.logs.keys(): + self.openLog(user) + ts = irc.timestamp() + print >>self.logs[user], "%s >>> :%s!%s@%s PRIVMSG %s :%s" % (ts, IRC.identity.nick, IRC.identity.username, IRC.identity.host, user.nick, msg) + self.logs[user].flush() + + def onSendPrivAction(self, IRC, origin, user, action): + ### Called when bot sends an action (/me) to a user. + ### The variable origin refers to a class instance voluntarily identifying itself as that which requested data be sent. + self.onSendPrivMsg(IRC, origin, user, "\x01ACTION %s\x01"%action) + + def onNickChange(self, IRC, user, newnick): + ### Called when somebody changes nickname. + ts = irc.timestamp() + line = "%s <<< :%s!%s@%s NICK %s" % ( + ts, user.nick, user.username, user.host, newnick) + + ### Print nick change in each channel the user is in. + for channel in user.channels: + print >>self.logs[channel], line + self.logs[channel].flush() + + ### And in the query if open. + if user in self.logs.keys(): + print >>self.logs[user], line + self.logs[user].flush() + + def onMeNickChange(self, IRC, newnick): + ### Called when the bot changes nickname. + + ### Print nick change to all open queries, except for query with self (already done with onNickChange). + ts = irc.timestamp() + line = "%s <<< :%s!%s@%s NICK %s" % (ts, IRC.identity.nick, + IRC.identity.username, IRC.identity.host, newnick) + for (window, log) in self.logs.items(): + if type(window) == irc.User and window != IRC.identity: + print >>log, line + log.flush() + + def onQuit(self, IRC, user, quitmsg): + ### Called when somebody quits IRC. + ts = irc.timestamp() + if quitmsg: + line = "%s <<< :%s!%s@%s QUIT :%s" % ( + ts, user.nick, user.username, user.host, quitmsg) + else: + line = "%s <<< :%s!%s@%s QUIT" % ( + ts, user.nick, user.username, user.host) + + ### Print quit in each channel the user was in. + for channel in user.channels: + if channel in self.logs.keys() and not self.logs[channel].closed: + print >>self.logs[channel], line + self.logs[channel].flush() + + ### And in the query if open. + if user in self.logs.keys(): + print >>self.logs[user], line + self.logs[user].flush() + self.closeLog(user) + + def onNames(self, IRC, origin, channel, flag, channame, nameslist): + ### Called when a NAMES list is received. + if channel in self.logs.keys() and not self.logs[channel].closed: + log = self.logs[channel] + else: + log = self.logs[IRC] + ts = irc.timestamp() + + secret = "s" in channel.modes.keys() and channel.modes["s"] + private = "p" in channel.modes.keys() and channel.modes["p"] + modes, symbols = channel.context.supports["PREFIX"] + print >>log, "%s <<< :%s 353 %s %s %s :%s" % (ts, origin, IRC.identity.nick, flag, channame, + " ".join(["%s%s!%s@%s"%(prefix, nick, username, host) if username and host else "%s%s"%(prefix, nick) for (prefix, nick, username, host) in nameslist])) + log.flush() + + def onNamesEnd(self, IRC, origin, channel, channame, endmsg): + if channel in self.logs.keys() and not self.logs[channel].closed: + log = self.logs[channel] + else: + log = self.logs[IRC] + ts = irc.timestamp() + print >>log, "%s <<< :%s 366 %s %s :%s" % ( + ts, origin, IRC.identity.nick, channame, endmsg) + log.flush() + + def onWhoisStart(self, IRC, origin, user, nickname, username, host, realname): + ### Called when a WHOIS reply is received. + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 311 %s %s %s %s * :%s" % (irc.timestamp(), origin, IRC.identity.nick, nickname, username, host, realname) + + def onWhoisRegisteredNick(self, IRC, origin, user, nickname, msg): + ### Called when a WHOIS reply is received. + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 307 %s %s :%s" % ( + irc.timestamp(), origin, IRC.identity.nick, nickname, msg) + + def onWhoisAway(self, IRC, origin, user, nickname, awaymsg): + ### Called when a WHOIS reply is received. + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 301 %s %s :%s" % (irc.timestamp( + ), origin, IRC.identity.nick, nickname, awaymsg) + + def onWhoisConnectingFrom(self, IRC, origin, user, nickname, msg): + ### Called when a WHOIS reply is received. + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 378 %s %s :%s" % ( + irc.timestamp(), origin, IRC.identity.nick, nickname, msg) + + def onWhoisChannels(self, IRC, origin, user, nickname, chanlist): + ### Called when a WHOIS reply is received. + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 319 %s %s :%s" % (irc.timestamp(), + origin, IRC.identity.nick, nickname, " ".join(chanlist)) + + def onWhoisAvailability(self, IRC, origin, user, nickname, msg): + ### Called when a WHOIS reply is received. + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 310 %s %s :%s" % ( + irc.timestamp(), origin, IRC.identity.nick, nickname, msg) + + def onWhoisServer(self, IRC, origin, user, nickname, server, servername): + ### Called when a WHOIS reply is received. + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 312 %s %s %s :%s" % (irc.timestamp(), origin, IRC.identity.nick, nickname, server, servername) + + def onWhoisOp(self, IRC, origin, user, nickname, msg): + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 313 %s %s :%s" % ( + irc.timestamp(), origin, IRC.identity.nick, nickname, msg) + + def onWhoisTimes(self, IRC, origin, user, nickname, idletime, signontime, msg): + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 317 %s %s %d %d :%s" % (irc.timestamp(), origin, IRC.identity.nick, nickname, idletime, signontime, msg) + + def onWhoisSSL(self, IRC, origin, user, nickname, msg): + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 671 %s %s :%s" % ( + irc.timestamp(), origin, IRC.identity.nick, nickname, msg) + + def onWhoisModes(self, IRC, origin, user, nickname, msg): + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 339 %s %s :%s" % ( + irc.timestamp(), origin, IRC.identity.nick, nickname, msg) + + def onWhoisLoggedInAs(self, IRC, origin, user, nickname, loggedinas, msg): + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 330 %s %s %s :%s" % (irc.timestamp(), origin, IRC.identity.nick, nickname, loggedinas, msg) + + def onWhoisEnd(self, IRC, origin, user, nickname, msg): + if user not in self.logs.keys(): + self.openLog(user) + print >>self.logs[user], "%s <<< :%s 318 %s %s :%s" % ( + irc.timestamp(), origin, IRC.identity.nick, nickname, msg) + self.logs[user].flush() + + def onWhoEntry(self, IRC, **kwargs): + ### Called when a WHO list is received. + pass + + def onWhoEnd(self, IRC, **kwargs): + ### Called when a WHO list is received. + pass + + def onList(self, IRC, chanlistbegin, chanlist, endmsg): + ### Called when a channel list is received. + pass + + def onTopic(self, IRC, origin, channel, topic): + ### Called when channel topic is received via 332 response. + ts = irc.timestamp() + if channel in self.logs.keys() and not self.logs[channel].closed: + log = self.logs[channel] + else: + log = self.logs[IRC] + print >>log, "%s <<< :%s 332 %s %s :%s" % ( + ts, origin, IRC.identity.nick, channel.name, topic) + log.flush() + + def onTopicInfo(self, IRC, origin, channel, topicsetby, topictime): + ### Called when channel topic info is received via 333 response. + ts = irc.timestamp() + if channel in self.logs.keys() and not self.logs[channel].closed: + log = self.logs[channel] + else: + log = self.logs[IRC] + print >>log, "%s <<< :%s 333 %s %s %s %d" % (ts, origin, + IRC.identity.nick, channel.name, topicsetby, topictime) + log.flush() + + def onTopicSet(self, IRC, user, channel, topic): + ### Called when channel topic is changed. + ts = irc.timestamp() + print >>self.logs[channel], "%s <<< :%s!%s@%s TOPIC %s :%s" % (ts, + user.nick, user.username, user.host, channel.name, topic) + self.logs[channel].flush() + + def onChanModeSet(self, IRC, user, channel, modedelta): + ### Called when channel modes are changed. + ### modedelta is a list of tuples of the format ("+x", parameter), ("+x", None) if no parameter is provided. + ts = irc.timestamp() + modestr = "" + params = [] + sign = "" + for (sgn, modechar), param in modedelta: + if sgn != sign: + modestr += sgn + sign = sgn + modestr += modechar + if param is not None: + params.append(param.nick if type(param) == irc.User else param) + if len(params): + if type(user) == irc.User: + print >>self.logs[channel], "%s <<< :%s!%s@%s MODE %s %s %s" % (ts, user.nick, user.username, user.host, channel.name, modestr, " ".join(params)) else: - print >>self.consolelogs[IRC], "%s %s >>> :%s!%s@%s %s" % (timestamp, time.tzname[now[-1]], IRC.identity.nick, IRC.identity.idnt, IRC.identity.host, line) - self.consolelogs[IRC].flush() - if IRC.registered and len(target) and (target[0] in IRC.supports["CHANTYPES"] or (len(target) > 1 and target[0] in IRC.supports["PREFIX"][1] and target[1] in IRC.supports["CHANTYPES"])) and cmd == "NOTICE": - channel = IRC.channel(target[1:] if target[0] - in IRC.supports["PREFIX"][1] else target) - if channel in IRC.identity.channels: - classes = " ".join([modemapping[mode] for mode in IRC.supports["PREFIX"][0] if mode in channel.modes.keys() and IRC.identity in channel.modes[mode]]) - if classes: - print >>self.channellogs[channel], "%s %s %s >>> :%s!%s@%s %s" % (timestamp, time.tzname[now[-1]], classes, IRC.identity.nick, IRC.identity.idnt, IRC.identity.host, line) - else: - print >>self.channellogs[channel], "%s %s >>> :%s!%s@%s %s" % (timestamp, time.tzname[now[-1]], IRC.identity.nick, IRC.identity.idnt, IRC.identity.host, line) - self.channellogs[channel].flush() + print >>self.logs[channel], "%s <<< :%s MODE %s %s %s" % (ts, user, channel.name, modestr, " ".join(params)) + else: + if type(user) == irc.User: + print >>self.logs[channel], "%s <<< :%s!%s@%s MODE %s %s" % (ts, user.nick, user.username, user.host, channel.name, modestr) else: - print >>self.consolelogs[IRC], "%s %s >>> :%s!%s@%s %s" % (timestamp, time.tzname[now[-1]], IRC.identity.nick, IRC.identity.idnt, IRC.identity.host, line) - self.consolelogs[IRC].flush() + print >>self.logs[channel], "%s <<< :%s MODE %s %s" % ( + ts, user, channel.name, modestr) + self.logs[channel].flush() + + def onChannelModes(self, IRC, channel, modedelta): + ### Called when channel modes are received via 324 response. + ts = irc.timestamp() + if channel in self.logs.keys() and not self.logs[channel].closed: + log = self.logs[channel] + else: + log = self.logs[IRC] + modestr = "" + params = [] + sign = "" + for (sgn, modechar), param in modedelta: + if sgn != sign: + modestr += sgn + sign = sgn + modestr += modechar + if param is not None: + params.append(param) + if len(params): + print >>log, "%s <<< :%s 324 %s %s %s %s" % (ts, IRC.serv, IRC.identity.nick, channel.name, modestr, " ".join(params)) + else: + print >>log, "%s <<< :%s 324 %s %s %s" % (ts, IRC.serv, + IRC.identity.nick, channel.name, modestr) + log.flush() + + def onChanCreated(self, IRC, channel, created): + ### Called when a 329 response is received. + ts = irc.timestamp() + if channel in self.logs.keys() and not self.logs[channel].closed: + log = self.logs[channel] + else: + log = self.logs[IRC] + print >>log, "%s <<< :%s 329 %s %s %d" % ( + ts, IRC.serv, IRC.identity.nick, channel.name, created) + log.flush() + + def onUnhandled(self, IRC, line, origin, cmd, target, params, extinfo): + ts = irc.timestamp() + print >>self.logs[IRC], "%s <<< %s" % (ts, line) + self.logs[IRC].flush() |