diff --git a/plugins/Alias.py b/plugins/Alias.py index 5a5c66e9f..9f677f826 100644 --- a/plugins/Alias.py +++ b/plugins/Alias.py @@ -43,7 +43,6 @@ import sets import types import conf -import debug import utils import privmsgs import callbacks diff --git a/plugins/Bugzilla.py b/plugins/Bugzilla.py index a07965bb4..601c96886 100644 --- a/plugins/Bugzilla.py +++ b/plugins/Bugzilla.py @@ -34,6 +34,8 @@ Bugzilla bug retriever """ +__revision__ = "$Id$" + import os import re import string @@ -43,9 +45,7 @@ from itertools import imap, ifilter from htmlentitydefs import entitydefs as entities import conf -import debug import utils -__revision__ = "$Id$" import plugins import ircutils @@ -194,13 +194,10 @@ class Bugzilla(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): try: name = self.shorthand[name] (url, description) = self.db[name] - #debug.printf(url) - #debug.printf(description) except KeyError: irc.error(msg, replyNoBugzilla % name) return queryurl = '%s/xml.cgi?id=%s' % (url, number) - #debug.printf(queryurl) try: summary = self._get_short_bug_summary(queryurl,description,number) except BugzillaError, e: diff --git a/plugins/ChannelDB.py b/plugins/ChannelDB.py index 42d06a181..40aee2f14 100644 --- a/plugins/ChannelDB.py +++ b/plugins/ChannelDB.py @@ -50,7 +50,6 @@ from itertools import imap, ifilter import sqlite import conf -import debug import utils import ircdb import ircmsgs @@ -359,7 +358,6 @@ class ChannelDB(plugins.ChannelDBHandler, cursor = db.cursor() (optlist, rest) = getopt.getopt(args, '', ['user']) name = privmsgs.getArgs(rest) - #debug.printf(optlist) if ('--user', '') in optlist: table = 'user_stats' criterion = 'user_id=%s' @@ -376,7 +374,6 @@ class ChannelDB(plugins.ChannelDBHandler, criterion = 'normalized=%s' name = ircutils.toLower(name) sql = "SELECT last_seen,last_msg FROM %s WHERE %s" % (table,criterion) - #debug.printf(sql) cursor.execute(sql, name) if cursor.rowcount == 0: irc.reply(msg, 'I have not seen %s.' % name) diff --git a/plugins/ChannelLogger.py b/plugins/ChannelLogger.py index 3e1019497..a1bdc2bfa 100644 --- a/plugins/ChannelLogger.py +++ b/plugins/ChannelLogger.py @@ -42,7 +42,6 @@ from cStringIO import StringIO import os import conf -import debug import world import irclib import ircmsgs @@ -85,7 +84,7 @@ class ChannelLogger(irclib.IrcCallback): log.flush() except ValueError, e: if e.args[0] != 'I/O operation on a closed file': - debug.recoverableException() + self.log.exception('Odd exception:') def getLog(self, channel): if channel in self.logs: @@ -96,7 +95,7 @@ class ChannelLogger(irclib.IrcCallback): self.logs[channel] = log return log except IOError: - debug.recoverableException() + self.log.exception('Error opening log:') return StringIO() def timestamp(self, log): diff --git a/plugins/Ctcp.py b/plugins/Ctcp.py index 8ad77a1cb..939b0ac90 100644 --- a/plugins/Ctcp.py +++ b/plugins/Ctcp.py @@ -45,7 +45,6 @@ import time sys.path.append(os.pardir) import conf -import debug import ircmsgs import callbacks @@ -55,34 +54,34 @@ class Ctcp(callbacks.PrivmsgRegexp): public = False def ping(self, irc, msg, match): "\x01PING (.*)\x01" - debug.msg('Received CTCP PING from %s' % msg.nick, 'normal') + self.log.info('Received CTCP PING from %s', msg.prefix) irc.queueMsg(notice(msg.nick, '\x01PING %s\x01' % match.group(1))) def version(self, irc, msg, match): "\x01VERSION\x01" - debug.msg('Received CTCP VERSION from %s' % msg.nick, 'normal') + self.log.info('Received CTCP VERSION from %s', msg.prefix) s = '\x01VERSION SupyBot %s\x01' % conf.version irc.queueMsg(notice(msg.nick, s)) def userinfo(self, irc, msg, match): "\x01USERINFO\x01" - debug.msg('Received CTCP USERINFO from %s' % msg.nick, 'normal') + self.log.info('Received CTCP USERINFO from %s', msg.prefix) irc.queueMsg(notice(msg.nick, '\x01USERINFO\x01')) def time(self, irc, msg, match): "\x01TIME\x01" - debug.msg('Received CTCP TIME from %s' % msg.nick, 'normal') + self.log.info('Received CTCP TIME from %s' % msg.prefix) irc.queueMsg(notice(msg.nick, '\x01%s\x01' % time.ctime())) def finger(self, irc, msg, match): "\x01FINGER\x01" - debug.msg('Received CTCP FINGER from %s' % msg.nick, 'normal') + self.log.info('Received CTCP FINGER from %s' % msg.prefix) s = '\x01SupyBot, the best Python bot in existence!\x01' irc.queueMsg(notice(msg.nick, s)) def source(self, irc, msg, match): "\x01SOURCE\x01" - debug.msg('Received CTCP SOURCE from %s' % msg.nick, 'normal') + self.log.info('Received CTCP SOURCE from %s' % msg.prefix) s = 'http://www.sourceforge.net/projects/supybot/' irc.queueMsg(notice(msg.nick, s)) diff --git a/plugins/DCC.py b/plugins/DCC.py index 92817a03f..03d0b8b3e 100644 --- a/plugins/DCC.py +++ b/plugins/DCC.py @@ -41,7 +41,6 @@ import socket import textwrap import threading -import debug import utils import world import ircmsgs @@ -75,19 +74,18 @@ class DCC(callbacks.Privmsg): i = ircutils.dccIP(ip) sock.bind((host, 0)) port = sock.getsockname()[1] - debug.msg('DCC CHAT port opened at (%s, %s)' % (host, port), - 'normal') + self.log.info('DCC CHAT port opened at (%s, %s)', host, port) sock.listen(1) irc.queueMsg(ircmsgs.privmsg(msg.nick, '\x01DCC CHAT chat %s %s\x01' % \ (i, port))) (realSock, addr) = sock.accept() - debug.msg('DCC CHAT accepted from %s' % (addr,), 'normal') + self.log.info('DCC CHAT accepted from %s', addr) for line in textwrap.wrap(text, 80): realSock.send(line) realSock.send('\n') finally: - debug.msg('Finally closing sock and realSock.', 'normal') + self.log.info('Finally closing sock and realSock.') sock.close() try: realSock.close() diff --git a/plugins/Dict.py b/plugins/Dict.py index 3bfe2021b..e88451a1e 100644 --- a/plugins/Dict.py +++ b/plugins/Dict.py @@ -44,7 +44,6 @@ import socket import dictclient import conf -import debug import utils import plugins import ircutils diff --git a/plugins/Ebay.py b/plugins/Ebay.py index fc7dabfa3..6a6185dd9 100644 --- a/plugins/Ebay.py +++ b/plugins/Ebay.py @@ -43,7 +43,6 @@ __revision__ = "$Id$" import plugins import conf -import debug import utils import plugins import ircutils @@ -132,11 +131,10 @@ class Ebay(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): if not self.configurables.get('auction-snarfer', channel=msg.args[0]): return url = match.group(0) - #debug.printf(url) try: irc.reply(msg, self._getResponse(url), prefixName=False) except EbayError, e: - debug.msg('Ebay Auction Snarfer: %s: %s' % (url, e)) + self.log.exception('ebaySnarfer exception at %s:', url) ebaySnarfer = privmsgs.urlSnarfer(ebaySnarfer) def _getResponse(self, url): @@ -162,7 +160,6 @@ class Ebay(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): m = r.search(s) if m: if r in self._multiField: - #debug.printf(m.groups()) # [:3] is to make sure that we don't pass a tuple with # more than 3 items. this allows self._bidder to work # since self._bidder returns a 5 item tuple diff --git a/plugins/Enforcer.py b/plugins/Enforcer.py index 1d144d74d..a516934b9 100644 --- a/plugins/Enforcer.py +++ b/plugins/Enforcer.py @@ -39,7 +39,6 @@ __revision__ = "$Id$" import plugins import conf -import debug import ircdb import ircmsgs import plugins @@ -104,7 +103,7 @@ class Enforcer(callbacks.Privmsg, plugins.Configurable): def doJoin(self, irc, msg): if not self.started: - debug.msg('Enforcer not started.', 'normal') + self.log.warning('Enforcer not started.') return channel = msg.args[0] c = ircdb.channels.getChannel(channel) @@ -123,7 +122,7 @@ class Enforcer(callbacks.Privmsg, plugins.Configurable): def doTopic(self, irc, msg): if not self.started: - debug.msg('Enforcer not started.', 'normal') + self.log.info('Enforcer not started.') return channel = msg.args[0] topic = msg.args[1] @@ -142,7 +141,7 @@ class Enforcer(callbacks.Privmsg, plugins.Configurable): def do332(self, irc, msg): # This command gets sent right after joining a channel. if not self.started: - debug.msg('Enforcer not started.', 'normal') + self.log.info('Enforcer not started.') return (channel, topic) = msg.args[1:] self.topics[channel] = topic @@ -157,7 +156,7 @@ class Enforcer(callbacks.Privmsg, plugins.Configurable): def doKick(self, irc, msg): if not self.started: - debug.msg('Enforcer not started.', 'normal') + self.log.info('Enforcer not started.') return channel = msg.args[0] kicked = msg.args[1].split(',') @@ -182,7 +181,7 @@ class Enforcer(callbacks.Privmsg, plugins.Configurable): def doMode(self, irc, msg): if not self.started: - debug.msg('Enforcer not started.', 'normal') + self.log.info('Enforcer not started.') return channel = msg.args[0] if not ircutils.isChannel(channel) or msg.nick == self.chanserv: @@ -246,9 +245,6 @@ class Enforcer(callbacks.Privmsg, plugins.Configurable): if ircutils.isUserHostmask(msg.prefix) and \ not msg.nick == self.chanserv: return callbacks.Privmsg.__call__(self, irc, msg) - else: - debug.msg('Enforcer plugin not started. ' - 'Give the bot the start command.', 'normal') Class = Enforcer diff --git a/plugins/Factoids.py b/plugins/Factoids.py index f05aa493e..2172229ee 100644 --- a/plugins/Factoids.py +++ b/plugins/Factoids.py @@ -410,4 +410,5 @@ class Factoids(plugins.ChannelDBHandler, callbacks.Privmsg): Class = Factoids + # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/plugins/FixRelayBot.py b/plugins/FixRelayBot.py index 471e5bcfe..37fc787a9 100644 --- a/plugins/FixRelayBot.py +++ b/plugins/FixRelayBot.py @@ -49,10 +49,8 @@ class FixRelayBot(irclib.IrcCallback): _re = re.compile(r'<([^@]+)@[^>]+>\s+(.*)') def inFilter(self, irc, msg): if msg.command == 'PRIVMSG': - #debug.printf('Message command was PRIVMSG') m = self._re.match(msg.args[1]) if m: - #debug.printf('Regexp matched: %r, %r, %r' % m.groups()) nick = m.group(1) host = random.random()*100 newprefix = ircutils.joinHostmask(nick, nick, host) diff --git a/plugins/Friendly.py b/plugins/Friendly.py index 7f15602b6..e466e43f2 100755 --- a/plugins/Friendly.py +++ b/plugins/Friendly.py @@ -37,7 +37,6 @@ __revision__ = "$Id$" import plugins -import debug import ircutils import callbacks diff --git a/plugins/Fun.py b/plugins/Fun.py index 226a608f7..9e5e58421 100644 --- a/plugins/Fun.py +++ b/plugins/Fun.py @@ -50,7 +50,6 @@ import mimetypes from itertools import imap import conf -import debug import utils import ircmsgs import ircutils diff --git a/plugins/FunDB.py b/plugins/FunDB.py index c0194f44e..de05dd918 100755 --- a/plugins/FunDB.py +++ b/plugins/FunDB.py @@ -48,7 +48,6 @@ from itertools import imap import sqlite import conf -import debug import ircdb import utils import world @@ -241,7 +240,7 @@ class FunDB(callbacks.Privmsg, plugins.Configurable): except ValueError, e: irc.error(msg, 'The regexp wasn\'t valid: %s.' % e.args[0]) except re.error, e: - irc.error(msg, debug.exnToString(e)) + irc.error(msg, utils.exnToString(e)) return db = self.dbHandler.getDb() cursor = db.cursor() diff --git a/plugins/Gameknot.py b/plugins/Gameknot.py index cfcadce37..74bc744c4 100644 --- a/plugins/Gameknot.py +++ b/plugins/Gameknot.py @@ -42,7 +42,6 @@ import sets import urllib2 import conf -import debug import utils import plugins import ircutils @@ -183,12 +182,9 @@ class Gameknot(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): r"http://(?:www\.)?gameknot\.com/chess\.pl\?bd=\d+(&r=\d+)?" if not self.configurables.get('game-snarfer', channel=msg.args[0]): return - #debug.printf('Got a GK URL from %s' % msg.prefix) url = match.group(0) fd = urllib2.urlopen(url) - #debug.printf('Got the connection.') s = fd.read() - #debug.printf('Got the string.') fd.close() try: if 'no longer available' in s: @@ -197,13 +193,13 @@ class Gameknot(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): return m = self._gkGameTitle.search(s) if m is None: - debug.msg('Gameknot._gkGameTitle didn\'t match (%s).' % url) + self.log.warning('_gkGameTitle didn\'t match (%s).', url) return gameTitle = m.groups() gameTitle = ircutils.bold(gameTitle) L = self._gkPlayer.findall(s) if not L: - debug.msg('Gameknot._gkPlayer didn\'t match (%s).' % url) + self.log.warning('_gkPlayer didn\'t match (%s).', url) return ((wRating, wName), (bRating, bName)) = L wName = ircutils.bold(wName) @@ -242,7 +238,7 @@ class Gameknot(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): irc.error(msg,'That doesn\'t appear to be a proper Gameknot game.'\ ' (%s)' % conf.replyPossibleBug) except Exception, e: - irc.error(msg, debug.exnToString(e)) + irc.error(msg, utils.exnToString(e)) gameknotSnarfer = privmsgs.urlSnarfer(gameknotSnarfer) def gameknotStatsSnarfer(self, irc, msg, match): diff --git a/plugins/Google.py b/plugins/Google.py index 08e73774b..16951c713 100644 --- a/plugins/Google.py +++ b/plugins/Google.py @@ -48,7 +48,6 @@ import SOAP import google import conf -import debug import utils import ircmsgs import plugins @@ -106,7 +105,7 @@ totalSearches = 0 totalTime = 0 last24hours = structures.queue() -def search(*args, **kwargs): +def search(log, *args, **kwargs): try: global totalSearches, totalTime, last24hours data = google.doGoogleSearch(*args, **kwargs) @@ -123,7 +122,7 @@ def search(*args, **kwargs): else: raise except SOAP.faultType, e: - debug.msg(debug.exnToString(e)) + log.exception('Uncaught SOAP error:') raise callbacks.Error, 'Invalid Google license key.' class Google(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): @@ -201,7 +200,7 @@ class Google(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): else: kwargs[option[2:]] = argument searchString = privmsgs.getArgs(rest) - data = search(searchString, **kwargs) + data = search(self.log, searchString, **kwargs) irc.reply(msg, self.formatData(data)) def metagoogle(self, irc, msg, args): @@ -222,7 +221,7 @@ class Google(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): else: kwargs[option[2:]] = argument searchString = privmsgs.getArgs(rest) - data = search(searchString, **kwargs) + data = search(self.log, searchString, **kwargs) meta = data.meta categories = [d['fullViewableName'] for d in meta.directoryCategories] categories = [utils.dqrepr(s.replace('_', ' ')) for s in categories] @@ -247,7 +246,7 @@ class Google(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): results = [] for arg in args: - data = search(arg) + data = search(self.log, arg) results.append((data.meta.estimatedTotalResultsCount, arg)) results.sort() results.reverse() @@ -286,7 +285,7 @@ class Google(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): return searchString = match.group(1) try: - data = search(searchString, safeSearch=1) + data = search(self.log, searchString, safeSearch=1) except google.NoLicenseKey: return if data.results: diff --git a/plugins/Http.py b/plugins/Http.py index 30085290b..540c2815e 100644 --- a/plugins/Http.py +++ b/plugins/Http.py @@ -47,7 +47,6 @@ from itertools import imap, ifilter import conf import utils -import debug import privmsgs import callbacks @@ -66,9 +65,14 @@ class Http(callbacks.Privmsg): def callCommand(self, method, irc, msg, *L): try: callbacks.Privmsg.callCommand(self, method, irc, msg, *L) - except socket.gaierror, e: - irc.error(msg, e.args[1]) - except urllib2.HTTPError, r: + except socket.error, e: + if e.args[0] == 111: + irc.error(msg, 'Connection refused.') + elif e.args[0] in (110, 10060): + irc.error(msg, 'Connection timed out.') + else: + irc.error(msg, e.args[1]) + except (urllib2.HTTPError, urllib2.URLError), e: irc.error(msg, str(e)) _titleRe = re.compile(r'(.*?)', re.I | re.S) @@ -115,7 +119,7 @@ class Http(callbacks.Privmsg): 'and a popularity of %s, is in version %s.' % \ (project, lastupdated, vitality, popularity, version)) except FreshmeatException, e: - irc.error(msg, debug.exnToString(e)) + irc.error(msg, utils.exnToString(e)) def stockquote(self, irc, msg, args): """ @@ -182,7 +186,6 @@ class Http(callbacks.Privmsg): city = '+'.join(args) city = city.rstrip(',') city = city.lower() - #debug.printf((state, city)) #We must break the States up into two sections. The US and #Canada are the only countries that require a State argument. @@ -199,7 +202,6 @@ class Http(callbacks.Privmsg): 'pass=&dpp=&forecast=zandh&config=&'\ 'place=%s&state=%s&country=%s' % \ (city, state, country) - #debug.printf(url) html = getPage(url) if 'was not found' in html: url = 'http://www.hamweather.net/cgi-bin/hw3/hw3.cgi?'\ @@ -290,7 +292,6 @@ class Http(callbacks.Privmsg): for (i, s) in enumerate(defs): if s.startswith('[not an acronym]'): defs[i] = s.split('is ', 1)[1] - #debug.printf(defs) if len(defs) == 0: irc.reply(msg,'No definitions found. (%s)'%conf.replyPossibleBug) else: diff --git a/plugins/Infobot.py b/plugins/Infobot.py index e12b49edc..3b47b39ef 100755 --- a/plugins/Infobot.py +++ b/plugins/Infobot.py @@ -43,7 +43,6 @@ import os.path import sqlite import conf -import debug import ircmsgs import callbacks @@ -205,7 +204,7 @@ if __name__ == '__main__': (key, value) = r.split(line, 1) cursor.execute(sql, key, value) except Exception, e: - print 'Invalid line (%s): %r' %(debug.exnToString(e),line) + print 'Invalid line (%s): %r' %(utils.exnToString(e),line) db.commit() diff --git a/plugins/Markov.py b/plugins/Markov.py index 1a70c0ff1..71e8fc977 100644 --- a/plugins/Markov.py +++ b/plugins/Markov.py @@ -44,7 +44,6 @@ import os.path import sqlite -import debug import ircmsgs import ircutils import privmsgs @@ -91,7 +90,6 @@ class Markov(plugins.ChannelDBHandler, callbacks.Privmsg): return channel = msg.args[0] db = self.getDb(channel) - #debug.printf([channel, db.db.filename]) cursor = db.cursor() if ircmsgs.isAction(msg): words = ircmsgs.unAction(msg).split() @@ -132,7 +130,6 @@ class Markov(plugins.ChannelDBHandler, callbacks.Privmsg): """ channel = privmsgs.getChannel(msg, args) db = self.getDb(channel) - #debug.printf([channel, db.db.filename]) cursor = db.cursor() words = [] cursor.execute("""SELECT id, first, second FROM pairs @@ -174,7 +171,6 @@ class Markov(plugins.ChannelDBHandler, callbacks.Privmsg): """ channel = privmsgs.getChannel(msg, args) db = self.getDb(channel) - #debug.printf([channel, db.db.filename]) cursor = db.cursor() cursor.execute("""SELECT COUNT(*) FROM pairs""") n = cursor.fetchone()[0] @@ -189,7 +185,6 @@ class Markov(plugins.ChannelDBHandler, callbacks.Privmsg): """ channel = privmsgs.getChannel(msg, args) db = self.getDb(channel) - #debug.printf([channel, db.db.filename]) cursor = db.cursor() cursor.execute("""SELECT COUNT(*) FROM pairs WHERE is_first=1""") n = cursor.fetchone()[0] @@ -204,7 +199,6 @@ class Markov(plugins.ChannelDBHandler, callbacks.Privmsg): """ channel = privmsgs.getChannel(msg, args) db = self.getDb(channel) - #debug.printf([channel, db.db.filename]) cursor = db.cursor() cursor.execute("""SELECT COUNT(*) FROM follows""") n = cursor.fetchone()[0] @@ -219,7 +213,6 @@ class Markov(plugins.ChannelDBHandler, callbacks.Privmsg): """ channel = privmsgs.getChannel(msg, args) db = self.getDb(channel) - #debug.printf([channel, db.db.filename]) cursor = db.cursor() cursor.execute("""SELECT COUNT(*) FROM follows WHERE word ISNULL""") n = cursor.fetchone()[0] diff --git a/plugins/Math.py b/plugins/Math.py index 22bb02b7d..c5f7b7c4f 100644 --- a/plugins/Math.py +++ b/plugins/Math.py @@ -46,7 +46,6 @@ from itertools import imap import unum.units -import debug import utils import privmsgs import callbacks @@ -120,7 +119,6 @@ class Math(callbacks.Privmsg): text = privmsgs.getArgs(args) text = text.translate(string.ascii, '_[] \t') text = text.replace('lambda', '') - #debug.printf(text) def handleMatch(m): s = m.group(1) if s.startswith('0x'): @@ -137,7 +135,6 @@ class Math(callbacks.Privmsg): x = abs(x) return str(x) text = self._mathRe.sub(handleMatch, text) - #debug.printf(text) try: x = complex(eval(text, self._mathEnv, self._mathEnv)) irc.reply(msg, self._complexToString(x)) @@ -149,7 +146,7 @@ class Math(callbacks.Privmsg): except NameError, e: irc.error(msg, '%s is not a defined function.' % str(e).split()[1]) except Exception, e: - irc.error(msg, debug.exnToString(e)) + irc.error(msg, utils.exnToString(e)) _rpnEnv = { 'dup': lambda s: s.extend([s.pop()]*2), diff --git a/plugins/MoobotFactoids.py b/plugins/MoobotFactoids.py index 2d376a6a6..f920ea761 100644 --- a/plugins/MoobotFactoids.py +++ b/plugins/MoobotFactoids.py @@ -36,7 +36,7 @@ command, it checks the factoid database for a key that matches what was said and if nothing is found, responds with an entry from the "dunno" database. """ -__revision__ = "$Id$" +__revision__="$Id$" import plugins @@ -51,7 +51,6 @@ from itertools import imap from cStringIO import StringIO import conf -import debug import ircdb import utils import ircmsgs diff --git a/plugins/Network.py b/plugins/Network.py index 0b951828d..1e0b7cab0 100644 --- a/plugins/Network.py +++ b/plugins/Network.py @@ -41,7 +41,6 @@ import sets import socket import telnetlib -import debug import utils import ircutils import privmsgs @@ -119,7 +118,6 @@ class Network(callbacks.Privmsg): (domain, url, status, created, updated, expires) irc.reply(msg, s) except NameError, e: - #debug.printf(e) irc.error(msg, 'I couldn\'t find such a domain.') diff --git a/plugins/Note.py b/plugins/Note.py index ca0cfc639..0e3861e04 100644 --- a/plugins/Note.py +++ b/plugins/Note.py @@ -45,7 +45,6 @@ from itertools import imap import sqlite import conf -import debug import utils import ircdb import ircmsgs diff --git a/plugins/OSU.py b/plugins/OSU.py index a93db93db..b3f822d50 100644 --- a/plugins/OSU.py +++ b/plugins/OSU.py @@ -40,7 +40,6 @@ import plugins import urllib2 -import debug import utils import privmsgs import callbacks @@ -261,7 +260,7 @@ class OSU(callbacks.Privmsg): else: irc.reply(msg, 'Possible matches: %s' % ', '.join(emails)) except Exception, e: - irc.error(msg, debug.exnToString(e)) + irc.error(msg, utils.exnToString(e)) def building(self, irc, msg, args): """ diff --git a/plugins/Poll.py b/plugins/Poll.py index 9aed47248..4cd80e32e 100644 --- a/plugins/Poll.py +++ b/plugins/Poll.py @@ -38,17 +38,17 @@ __revision__ = "$Id$" import plugins +import os +import time + +import sqlite + +import conf import utils import ircdb import ircutils import privmsgs import callbacks -import conf -import debug - -import os.path -import time -import sqlite def configure(onStart, afterConnect, advanced): diff --git a/plugins/Python.py b/plugins/Python.py index bb667f4dd..cdf56db8d 100644 --- a/plugins/Python.py +++ b/plugins/Python.py @@ -53,7 +53,6 @@ sys.stdout = StringIO() import this sys.stdout = sys.__stdout__ -import debug import utils import ircutils import privmsgs @@ -200,7 +199,6 @@ class Python(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): if m: resp.append('%s: %s' % self._bold(m.groups())) if resp: - #debug.printf('; '.join(resp)) irc.reply(msg, '; '.join(resp), prefixName = False) aspnRecipes = privmsgs.urlSnarfer(aspnRecipes) diff --git a/plugins/Quotes.py b/plugins/Quotes.py index 76df34e50..da21e113b 100644 --- a/plugins/Quotes.py +++ b/plugins/Quotes.py @@ -165,7 +165,6 @@ class Quotes(plugins.ChannelDBHandler, callbacks.Privmsg): formats.append(s) sql = """SELECT id, quote FROM quotes WHERE %s""" % ' AND '.join(criteria) - #debug.printf(sql) cursor = db.cursor() cursor.execute(sql, *formats) if cursor.rowcount == 0: diff --git a/plugins/Relay.py b/plugins/Relay.py index 102df51e9..ff2fabd3c 100644 --- a/plugins/Relay.py +++ b/plugins/Relay.py @@ -43,7 +43,6 @@ import time from itertools import imap, ifilter import conf -import debug import utils import world import irclib diff --git a/plugins/Sourceforge.py b/plugins/Sourceforge.py index 3e923f5dc..7ea1065f7 100644 --- a/plugins/Sourceforge.py +++ b/plugins/Sourceforge.py @@ -41,7 +41,6 @@ import urllib2 from itertools import ifilter, imap import conf -import debug import utils __revision__ = "$Id$" @@ -159,7 +158,7 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): return 'http://sourceforge.net%s%s' % (utils.htmlToText( m.group(1)), self._hrefOpts) except urllib2.HTTPError, e: - raise callbacks.Error, e.msg() + raise callbacks.Error, str(e) def _getTrackerList(self, url): try: @@ -318,18 +317,17 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, plugins.Configurable): head = '%s #%s:' % (ircutils.bold(linktype), num) resp.append(desc) else: - debug.msg('%s does not appear to be a proper Sourceforge '\ - 'Tracker page (%s)' % (url, conf.replyPossibleBug)) + s = '%s does not appear to be a proper Sourceforge ' \ + 'Tracker page (%s)' % (url, conf.replyPossibleBug) + self.log.warning(s) for r in self._res: m = r.search(s) if m: resp.append('%s: %s' % self._bold(m.groups())) irc.reply(msg, '%s #%s: %s' % (ircutils.bold(linktype), ircutils.bold(num), '; '.join(resp)), prefixName = False) - except urllib2.HTTPError, e: - debug.msg(e.msg()) - except socket.error, e: - debug.msg(e.msg()) + except (urllib2.HTTPError, socket.error), e: + self.log.warning(str(e)) sfSnarfer = privmsgs.urlSnarfer(sfSnarfer) Class = Sourceforge diff --git a/plugins/Status.py b/plugins/Status.py index 34fb4ec97..74f2bc629 100644 --- a/plugins/Status.py +++ b/plugins/Status.py @@ -191,8 +191,8 @@ class Status(callbacks.Privmsg): elif sys.platform.startswith('netbsd'): mem = os.stat('/proc/%s/mem')[7] response += ' I\'m taking up %s kB of memory.' % mem - except Exception, e: - debug.msg(debug.exnToString(e)) + except Exception: + self.log.exception('Uncaught exception in cpustats:') irc.reply(msg, response) def cmdstats(self, irc, msg, args): diff --git a/plugins/Todo.py b/plugins/Todo.py index 3c6d9fe49..a110b0f0a 100644 --- a/plugins/Todo.py +++ b/plugins/Todo.py @@ -47,7 +47,6 @@ import os.path import sqlite import conf -import debug import ircdb import utils import privmsgs diff --git a/plugins/Topic.py b/plugins/Topic.py index 9d2ec77cf..ac446c62f 100644 --- a/plugins/Topic.py +++ b/plugins/Topic.py @@ -41,7 +41,6 @@ import re import random import conf -import debug import utils import ircdb import ircmsgs @@ -161,7 +160,7 @@ class Topic(callbacks.Privmsg): irc.error(msg, 'The regexp wasn\'t valid: %s' % e.args[0]) return except re.error, e: - irc.error(msg, debug.exnToString(e)) + irc.error(msg, utils.exnToString(e)) return topics = self._splitTopic(irc.state.getTopic(channel)) if not topics: @@ -214,7 +213,6 @@ class Topic(callbacks.Privmsg): except IndexError: irc.error(msg, 'That\'s not a valid topic number.') return - ## debug.printf(topic) match = self.topicUnformatter.match(topic) if match is None: name = '' diff --git a/plugins/URL.py b/plugins/URL.py index b10645226..cb7593ecb 100644 --- a/plugins/URL.py +++ b/plugins/URL.py @@ -49,7 +49,6 @@ import urlparse import sqlite import conf -import debug import utils import ircmsgs import ircutils @@ -176,10 +175,9 @@ class URL(callbacks.PrivmsgCommandAndRegexp, cursor = db.cursor() (tinyurl, updateDb) = self._getTinyUrl(url, channel) if tinyurl is None: - debug.msg('tinyurl was None for url %r' % url) + self.log.warning('tinyurl was None for url %r', url) return elif updateDb: - #debug.printf(url) self._updateTinyDb(url, tinyurl, channel) s = '%s (was <%s>)' % (ircutils.bold(tinyurl), url) irc.reply(msg, s, prefixName=False) @@ -206,7 +204,6 @@ class URL(callbacks.PrivmsgCommandAndRegexp, if cursor.rowcount == 0: updateDb = True try: - #debug.printf('Trying to get tinyurl for %r' % url) fd = urllib2.urlopen('http://tinyurl.com/create.php?url=%s' % url) s = fd.read() @@ -220,14 +217,13 @@ class URL(callbacks.PrivmsgCommandAndRegexp, if cmd: raise callbacks.Error, e.msg() else: - debug.msg(e.msg()) + self.log.warning(str(e)) else: updateDb = False tinyurl = cursor.fetchone()[0] return (tinyurl, updateDb) def _formatUrl(self, url, added, addedBy): - #debug.printf((url, added, addedBy)) when = time.strftime(conf.humanTimestampFormat, time.localtime(int(added))) return '<%s> (added by %s at %s)' % (url, addedBy, when) diff --git a/scripts/supybot-wizard b/scripts/supybot-wizard index 805f30b24..301a641d3 100755 --- a/scripts/supybot-wizard +++ b/scripts/supybot-wizard @@ -11,17 +11,17 @@ import sets import pydoc import pprint import socket +import logging import optparse import textwrap from itertools import imap import ansi import conf -import debug import utils import ircutils -debug.minimumPriority = 'high' +conf.minimumLogPriority = logging.CRITICAL useColor = False @@ -69,7 +69,7 @@ def loadPlugin(name): except Exception, e: myPrint("""We encountered a bit of trouble trying to load plugin %r. Python told us %r. We'll skip over it for now, you can always add it - later.""" % (name, debug.exnToString(e))) + later.""" % (name, utils.exnToString(e))) return None def describePlugin(module, showUsage): @@ -146,7 +146,6 @@ def main(): server = None onStart = [] afterConnect = [] - debugVariables = {} configVariables = {} myPrint("""This is a wizard to help you start running supybot. What it @@ -473,39 +472,39 @@ def main(): configVariables['enablePipeSyntax'] = True ### - # debug variables. + # logging variables. ### - # debug.stderr + # conf.stdoutLogging myPrint("""By default, your bot will log not only to files in the logs - directory you gave it, but also to stderr. We find this useful for + directory you gave it, but also to stdout. We find this useful for debugging, and also just for the pretty output (it's colored!)""") - if yn('Would you like to turn off this logging to stderr?') == 'y': - debugVariables['stderr'] = False + if yn('Would you like to turn off this logging to stdout?') == 'y': + confVariables['stdoutLogging'] = False else: - # debug.colorterm + # conf.something myPrint("""Some terminals may not be able to display the pretty colors logged to stderr. By default, though, we turn the colors off for Windows machines and leave it on for *nix machines.""") if yn('Would you like to turn this colorization off?') == 'y': - debugVariables['colorterm'] = False + confVariables['colorterm'] = False - # debug.minimumPriority - myPrint("""Your bot can handle debug messages at four priorities, 'high,' - 'normal,' 'low,' and 'verbose,' in decreasing order of priority. By - default, your bot will log all of these priorities. You can, however, - specify that he only log messages above a certain priority level. Of - course, all error messages will still be logged.""") - priority = anything('What would you like the minimum priority to be? ' - 'Just press enter to accept the default.') - while priority and priority not in ['verbose', 'low', 'normal', 'high']: - myPrint("""That's not a valid priority. Valid priorities include - 'verbose,' 'low,' 'normal,' and 'high,' not including the quotes or - the commas.""") - priority = anything('What would you like the minimum priority to be? ' - 'Just press enter to accept the default.') - if priority: - debugVariables['minimumPriority'] = priority +## # conf.minimumLogPriority +## myPrint("""Your bot can handle debug messages at several priorities, +## CRITICAL, in decreasing order of priority. By +## default, your bot will log all of these priorities. You can, however, +## specify that he only log messages above a certain priority level. Of +## course, all error messages will still be logged.""") +## priority = anything('What would you like the minimum priority to be? ' +## 'Just press enter to accept the default.') +## while priority and priority not in ['verbose', 'low', 'normal', 'high']: +## myPrint("""That's not a valid priority. Valid priorities include +## 'verbose,' 'low,' 'normal,' and 'high,' not including the quotes or +## the commas.""") +## priority = anything('What would you like the minimum priority to be? ' +## 'Just press enter to accept the default.') +## if priority: +## confVariables['minimumLogPriority'] = priority if advanced: myPrint("""Here's some stuff you only get to choose if you're an @@ -625,7 +624,6 @@ def main(): template = template.replace('"%%server%%"', repr(server)) template = template.replace('"%%onStart%%"', format(onStart)) template = template.replace('"%%afterConnect%%"', format(afterConnect)) - template = template.replace('"%%debugVariables%%"', format(debugVariables)) template = template.replace('"%%configVariables%%"', format(configVariables)) template = template.replace('/usr/bin/env python', diff --git a/src/Channel.py b/src/Channel.py index 95d5c30cd..05e4c765b 100755 --- a/src/Channel.py +++ b/src/Channel.py @@ -42,7 +42,6 @@ import time from itertools import imap import conf -import debug import ircdb import utils import ircmsgs diff --git a/src/Misc.py b/src/Misc.py index 5dfd4937d..f347f7864 100755 --- a/src/Misc.py +++ b/src/Misc.py @@ -43,7 +43,6 @@ import getopt from itertools import imap, ifilter import conf -import debug import utils import irclib import ircmsgs @@ -54,7 +53,7 @@ import callbacks class Misc(callbacks.Privmsg): priority = sys.maxint def invalidCommand(self, irc, msg, tokens): - #debug.printf('Misc.invalidCommand called') + self.log.debug('Misc.invalidCommand called') if conf.replyWhenNotCommand: command = tokens and tokens[0] or '' irc.error(msg, '%r is not a valid command.' % command) @@ -112,7 +111,8 @@ class Misc(callbacks.Privmsg): not isinstance(cb, callbacks.PrivmsgRegexp): for attr in dir(cb): if s in attr and cb.isCommand(attr): - commands.setdefault(attr, []).append(cb.name()) + if attr == callbacks.canonicalName(attr): + commands.setdefault(attr, []).append(cb.name()) for (key, names) in commands.iteritems(): if len(names) == 1: L.append(key) @@ -210,10 +210,13 @@ class Misc(callbacks.Privmsg): irc.error(msg, 'Module %s has no __revision__.' % name) else: def getVersion(s): - return s.split(None, 3)[2] + try: + return s.split(None, 3)[2] + except: + self.log.exception('Couldn\'t get id string: %r', s) names = {} dirs = map(os.path.abspath, conf.pluginDirs) - for (name, module) in sys.modules.iteritems(): + for (name, module) in sys.modules.items(): # Don't use iteritems. if hasattr(module, '__revision__'): if 'supybot' in module.__file__: names[name] = getVersion(module.__revision__) @@ -251,7 +254,10 @@ class Misc(callbacks.Privmsg): if file.endswith('.log'): stats = os.stat(os.path.join(conf.logDir, file)) result.append((file, str(stats.st_size))) - irc.reply(msg, ', '.join(imap(': '.join, result))) + if result: + irc.reply(msg, ', '.join(imap(': '.join, result))) + else: + irc.reply(msg, 'I couldn\'t find any logfiles.') def getprefixchar(self, irc, msg, args): """takes no arguments diff --git a/src/Owner.py b/src/Owner.py index fd44f4df9..26c8c4236 100644 --- a/src/Owner.py +++ b/src/Owner.py @@ -44,8 +44,8 @@ import imp import sys import linecache +import log import conf -import debug import utils import world import ircdb @@ -62,7 +62,7 @@ def loadPluginModule(name): try: files.extend(os.listdir(dir)) except EnvironmentError: - debug.msg('Invalid plugin directory: %s' % dir, 'verbose') + log.warning('Invalid plugin directory: %s', dir) loweredFiles = map(str.lower, files) try: index = loweredFiles.index(name.lower()+'.py') @@ -188,9 +188,9 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg): try: irc.reply(msg, repr(eval(s))) except SyntaxError, e: - irc.reply(msg, '%s: %r' % (debug.exnToString(e), s)) + irc.reply(msg, '%s: %r' % (utils.exnToString(e), s)) except Exception, e: - irc.reply(msg, debug.exnToString(e)) + irc.reply(msg, utils.exnToString(e)) else: irc.error(msg, conf.replyEvalNotAllowed) @@ -205,7 +205,7 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg): exec s irc.reply(msg, conf.replySuccess) except Exception, e: - irc.reply(msg, debug.exnToString(e)) + irc.reply(msg, utils.exnToString(e)) else: irc.error(msg, conf.replyEvalNotAllowed) @@ -222,7 +222,7 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg): try: value = eval(value) except Exception, e: - irc.error(msg, debug.exnToString(e)) + irc.error(msg, utils.exnToString(e)) return setattr(conf, name, value) irc.reply(msg, conf.replySuccess) @@ -279,22 +279,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg): conf.defaultCapabilities.remove(capability) irc.reply(msg, conf.replySuccess) - def settrace(self, irc, msg, args): - """takes no arguments - - Starts the function-tracing debug mode; beware that this makes *huge* - logfiles. - """ - sys.settrace(debug.tracer) - irc.reply(msg, conf.replySuccess) - - def unsettrace(self, irc, msg, args): - """takes no arguments - - Stops the function-tracing debug mode.""" - sys.settrace(None) - irc.reply(msg, conf.replySuccess) - def ircquote(self, irc, msg, args): """ @@ -303,10 +287,10 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg): s = privmsgs.getArgs(args) try: m = ircmsgs.IrcMsg(s) + except Exception, e: + irc.error(msg, utils.exnToString(e)) + else: irc.queueMsg(m) - except Exception: - debug.recoverableException() - irc.error(msg, conf.replyError) def quit(self, irc, msg, args): """[] @@ -321,7 +305,7 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg): driver.die() for irc in world.ircs[:]: irc.die() - debug.exit(i) + raise SystemExit def flush(self, irc, msg, args): """takes no arguments @@ -383,7 +367,7 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg): if name in str(e): irc.error(msg, 'No plugin %s exists.' % name) else: - irc.error(msg, debug.exnToString(e)) + irc.error(msg, utils.exnToString(e)) return loadPluginClass(irc, module) irc.reply(msg, conf.replySuccess) diff --git a/src/asyncoreDrivers.py b/src/asyncoreDrivers.py index 676e58edc..3d52b4a49 100644 --- a/src/asyncoreDrivers.py +++ b/src/asyncoreDrivers.py @@ -40,9 +40,9 @@ import socket import asyncore import asynchat -import repl +import log import conf -import debug +import repl import ircdb import world import drivers @@ -51,16 +51,15 @@ import schedule class AsyncoreRunnerDriver(drivers.IrcDriver): def run(self): - #debug.printf(asyncore.socket_map) + log.printf(repr(asyncore.socket_map)) try: asyncore.poll(conf.poll) except: - debug.recoverableException() + log.exception('Uncaught exception:') class AsyncoreDriver(asynchat.async_chat, object): def __init__(self, (server, port), irc): - #debug.methodNamePrintf(self, '__init__') asynchat.async_chat.__init__(self) self.server = (server, port) self.irc = irc @@ -71,22 +70,19 @@ class AsyncoreDriver(asynchat.async_chat, object): try: self.connect(self.server) except: - debug.recoverableException('terse') + log.exception('Error connecting:') self.close() def scheduleReconnect(self): - #debug.methodNamePrintf(self, 'scheduleReconnect') when = time.time() + 60 whenS = time.strftime(conf.logTimestampFormat, time.localtime(when)) - debug.msg('Scheduling reconnect to %s at %s' % (self.server, whenS), - 'normal') + log.info('Scheduling reconnect to %s at %s', self.server, whenS) def makeNewDriver(): self.irc.reset() driver = self.__class__(self.server, self.irc) schedule.addEvent(makeNewDriver, when) def writable(self): - #debug.methodNamePrintf(self, 'writable') while self.connected: m = self.irc.takeMsg() if m: @@ -96,38 +92,31 @@ class AsyncoreDriver(asynchat.async_chat, object): return asynchat.async_chat.writable(self) def handle_error(self): - #debug.recoverableException() self.handle_close() def collect_incoming_data(self, s): - #debug.methodNamePrintf(self, 'collect_incoming_data') self.buffer += s def found_terminator(self): - #debug.methodNamePrintf(self, 'found_terminator') start = time.time() msg = ircmsgs.IrcMsg(self.buffer) - debug.msg('Time to parse IrcMsg: %s' % (time.time()-start), 'verbose') + log.verbose('Time to parse IrcMsg: %s', time.time()-start) self.buffer = '' try: self.irc.feedMsg(msg) except: - debug.msg('Exception caught outside Irc object.', 'normal') - debug.recoverableException() + log.exception('Uncaught exception outside Irc object:') def handle_close(self): - #debug.methodNamePrintf(self, 'handle_close') self.scheduleReconnect() self.die() reconnect = handle_close def handle_connect(self): - #debug.methodNamePrintf(self, 'handle_connect') pass def die(self): - #debug.methodNamePrintf(self, 'die') self.close() @@ -141,7 +130,7 @@ class ReplListener(asyncore.dispatcher, object): def handle_accept(self): (sock, addr) = self.accept() - debug.msg('Connection made to telnet-REPL: ' + str(addr),'normal') + log.info('Connection made to telnet-REPL: %s', addr) Repl((sock, addr)) @@ -191,8 +180,7 @@ Name: """ % (world.version, sys.version.translate(string.ascii, '\r\n')) self.push('Unknown user.\n') self.tries += 1 self.prompt = 'Name: ' - msg = 'Unknown user %s on telnet REPL.' % name - debug.msg(msg,'high') + log.warning('Unknown user %s on telnet REPL.', name) self.push(self.prompt) elif self.u is not None and not self.authed: password = self.buffer @@ -205,16 +193,16 @@ Name: """ % (world.version, sys.version.translate(string.ascii, '\r\n')) self.push('Only owners can use this feature.\n') self.close() msg = 'Attempted non-owner user %s on telnet REPL' % name - debug.msg(msg, 'high') + log.warning(msg) else: self.push('Incorrect Password.\n') self.prompt = 'Name: ' self.u = None msg = 'Invalid password for user %s on telnet REPL.' % name - debug.msg(msg, 'high') + log.warning(msg) self.push(self.prompt) elif self.authed: - debug.msg('Telnet REPL: %s' % self.buffer) + log.info('Telnet REPL: %s', self.buffer) ret = self.repl.addLine(self.buffer+'\r\n') self.buffer = '' if ret is not repl.NotYet: diff --git a/src/callbacks.py b/src/callbacks.py index ab9345b0a..06c700450 100644 --- a/src/callbacks.py +++ b/src/callbacks.py @@ -56,8 +56,8 @@ import threading from itertools import imap, ifilter from cStringIO import StringIO +import log import conf -import debug import utils import world import ircdb @@ -199,7 +199,7 @@ class Tokenizer: ends = [] while True: token = lexer.get_token() - #debug.printf(repr(token)) + log.printf(repr(token)) if not token: break elif token == '|': @@ -239,7 +239,7 @@ def tokenize(s): _lastTokenized = None _lastTokenizedResult = None raise SyntaxError, str(e) - debug.msg('tokenize took %s seconds.' % (time.time() - start), 'verbose') + log.verbose('tokenize took %s seconds.' % (time.time() - start)) return copy.deepcopy(_lastTokenizeResult) def getCommands(tokens): @@ -276,7 +276,7 @@ def formatArgumentError(method, name=None): class IrcObjectProxy: "A proxy object to allow proper nested of commands (even threaded ones)." def __init__(self, irc, msg, args): - #debug.printf('IrcObjectProxy.__init__: %s' % args) + log.printf('IrcObjectProxy.__init__: %s' % args) self.irc = irc self.msg = msg self.args = args @@ -307,7 +307,7 @@ class IrcObjectProxy: def _callInvalidCommands(self): for cb in self.irc.callbacks: - #debug.printf('Trying to call %s.invalidCommand' % cb.name()) + log.printf('Trying to call %s.invalidCommand' % cb.name()) if self.finished: break if hasattr(cb, 'invalidCommand'): @@ -347,22 +347,21 @@ class IrcObjectProxy: del self.args[0] cb = cbs[0] anticap = ircdb.makeAntiCapability(name) - #debug.printf('Checking for %s' % anticap) + log.printf('Checking for %s' % anticap) if ircdb.checkCapability(self.msg.prefix, anticap): - #debug.printf('Being prevented with anticap') - debug.msg('Preventing %s from calling %s' % \ - (self.msg.nick, name), 'normal') + log.printf('Being prevented with anticap') + log.info('Preventing %s from calling %s' % + (self.msg.nick, name)) s = conf.replyNoCapability % name self.error(self.msg, s, private=True) return recipient = self.msg.args[0] if ircutils.isChannel(recipient): chancap = ircdb.makeChannelCapability(recipient, anticap) - #debug.printf('Checking for %s' % chancap) if ircdb.checkCapability(self.msg.prefix, chancap): - #debug.printf('Being prevented with chancap') - debug.msg('Preventing %s from calling %s' % \ - (self.msg.nick, name), 'normal') + log.printf('Being prevented with chancap') + log.info('Preventing %s from calling %s' % + (self.msg.nick, name)) s = conf.replyNoCapability % name self.error(self.msg, s, private=True) return @@ -380,10 +379,10 @@ class IrcObjectProxy: if not isinstance(self.irc, irclib.Irc): self.error(self.msg, 'Command %r cannot be nested.' % name) except (SyntaxError, Error), e: - self.reply(self.msg, debug.exnToString(e)) + self.reply(self.msg, utils.exnToString(e)) except Exception, e: - debug.recoverableException() - self.error(self.msg, debug.exnToString(e)) + log.exception('Uncaught exception in finalEval:') + self.error(self.msg, utils.exnToString(e)) def reply(self, msg, s, noLengthCheck=False, prefixName=True, action=False, private=False, notice=False, to=None): @@ -496,7 +495,7 @@ class CommandThread(threading.Thread): name = '%s.%s with args %r' % (self.className, self.commandName, args) threading.Thread.__init__(self, target=callCommand, name=name, args=(command, irc, msg, args)+L) - debug.msg('Spawning thread %s' % name, 'verbose') + log.verbose('Spawning thread %s' % name) self.irc = irc self.msg = msg self.setDaemon(True) @@ -512,10 +511,10 @@ class CommandThread(threading.Thread): s = 'Command %r cannot be nested.' % self.commandName self.irc.error(self.msg, s) except (SyntaxError, Error), e: - self.irc.reply(self.msg, debug.exnToString(e)) + self.irc.reply(self.msg, utils.exnToString(e)) except Exception, e: - debug.recoverableException() - self.irc.error(self.msg, debug.exnToString(e)) + log.exception('Uncaught exception in CommandThread.run:') + self.irc.error(self.msg, utils.exnToString(e)) class ConfigIrcProxy(object): @@ -527,7 +526,7 @@ class ConfigIrcProxy(object): return None def error(self, msg, s, *args): - debug.msg('ConfigIrcProxy saw an error: %s' % s, 'normal') + log.info('ConfigIrcProxy saw an error: %s' % s) def getRealIrc(self): irc = self.__dict__['irc'] @@ -554,7 +553,10 @@ class Privmsg(irclib.IrcCallback): def __init__(self): self.__parent = super(Privmsg, self) self.Proxy = IrcObjectProxy - canonicalname = canonicalName(self.name()) + myName = self.name() + self.log = log.getPluginLogger(myName) + ### Setup the dispatcher command. + canonicalname = canonicalName(myName) self._original = getattr(self, canonicalname, None) docstring = """ [ ...] @@ -562,7 +564,7 @@ class Privmsg(irclib.IrcCallback): commands provided by this plugin. In most cases this dispatcher command is unnecessary; in cases where more than one plugin defines a given command, use this command to tell the bot which plugin's command - to use.""" % (self.name(), self.name()) + to use.""" % (myName, myName) def dispatcher(self, irc, msg, args): def handleBadArgs(): if self._original: @@ -599,7 +601,7 @@ class Privmsg(irclib.IrcCallback): args = args[:] command = canonicalName(args.pop(0)) if self.isCommand(command): - #debug.printf('%s: %r' % (command, args)) + self.log.debug('%s: %r', command, args) method = getattr(self, command) line = '%s %s' % (command, ' '.join(imap(utils.dqrepr, args))) msg = ircmsgs.privmsg(fakeIrc.nick, line, fakeIrc.prefix) @@ -614,7 +616,7 @@ class Privmsg(irclib.IrcCallback): if self.noIgnore or not ircdb.checkIgnored(msg.prefix,msg.args[0]): self.__parent.__call__(irc, msg) else: - debug.msg('Ignoring %s.' % msg.prefix) + self.log.info('Ignoring %s', msg.prefix) else: self.__parent.__call__(irc, msg) @@ -637,8 +639,7 @@ class Privmsg(irclib.IrcCallback): start = time.time() f(irc, msg, *L) elapsed = time.time() - start - funcname = '%s.%s' % (f.im_class.__name__, f.im_func.func_name) - debug.msg('%s took %s seconds' % (funcname, elapsed), 'verbose') + self.log.info('%s took %s seconds', f.im_func.func_name, elapsed) class IrcObjectProxyRegexp(object): @@ -696,18 +697,15 @@ class PrivmsgRegexp(Privmsg): r = re.compile(value.__doc__, self.flags) self.res.append((r, value)) except re.error, e: - s = '%s.%s has an invalid regexp %s: %s' % \ - (self.__class__.__name__, name, - value.__doc__, debug.exnToString(e)) - debug.msg(s) + self.log.warning('Invalid regexp: %r (%s)',value.__doc__,e) self.res.sort(lambda (r1, m1), (r2, m2): cmp(m1.__name__, m2.__name__)) def callCommand(self, method, irc, msg, *L): try: self.__parent.callCommand(method, irc, msg, *L) except Exception, e: - debug.recoverableException() - irc.error(msg, debug.exnToString(e)) + self.log.exception('Uncaught exception from callCommand:') + irc.error(msg, utils.exnToString(e)) def doPrivmsg(self, irc, msg): for (r, method) in self.res: @@ -749,8 +747,8 @@ class PrivmsgCommandAndRegexp(Privmsg): self.__parent.callCommand(f, irc, msg, *L) except Exception, e: if 'catchErrors' in kwargs and kwargs['catchErrors']: - irc.error(msg, debug.exnToString(e)) - debug.recoverableException() + self.log.exception('Uncaught exception in callCommand:') + irc.error(msg, utils.exnToString(e)) else: raise diff --git a/src/conf.py b/src/conf.py index c9c5d10e7..19e5dbfc1 100644 --- a/src/conf.py +++ b/src/conf.py @@ -37,6 +37,7 @@ import sys import sets import os.path +import logging ### # Directions: @@ -59,6 +60,18 @@ pluginDirs = [os.path.join(installDir, s) for s in ('src', 'plugins')] userfile = 'users.conf' channelfile = 'channels.conf' +### +# minimumLogPriority: The minimum priority that will be logged. Defaults to +# logging.INFO, which is probably a good value. Can also +# be usefully set to logging.{DEBUG,WARNING,ERROR,CRITICAL} +### +minimumLogPriority = logging.INFO + +### +# stdoutLogging: Determines whether or not the bot logs to stdout. +### +stdoutLogging = True + ### # logTimestampFormat: A format string defining how timestamps should be. Check # the Python library reference for the "time" module to see diff --git a/src/drivers.py b/src/drivers.py index c81cc9224..daf01ba7f 100644 --- a/src/drivers.py +++ b/src/drivers.py @@ -41,9 +41,9 @@ import re import os import sys +import log import conf import ansi -import debug import ircmsgs _drivers = {} @@ -134,7 +134,7 @@ def run(): if name not in _deadDrivers: driver.run() except: - debug.recoverableException() + log.exception('Uncaught exception in in drivers.run:') _deadDrivers.append(name) for name in _deadDrivers: try: diff --git a/src/ircdb.py b/src/ircdb.py index daf082f13..bf30a58ad 100644 --- a/src/ircdb.py +++ b/src/ircdb.py @@ -39,8 +39,8 @@ import time import string from itertools import imap +import log import conf -import debug import utils import world import ircutils @@ -589,40 +589,30 @@ def _x(capability, ret): def _checkCapabilityForUnknownUser(capability, users=users, channels=channels): if isChannelCapability(capability): - #debug.printf('isChannelCapability true.') (channel, capability) = fromChannelCapability(capability) try: c = channels.getChannel(channel) if capability in c.capabilities: - #debug.printf('capability in c.capabilities') return c.checkCapability(capability) else: - #debug.printf('capability not in c.capabilities') return _x(capability, c.defaultAllow) except KeyError: - #debug.printf('no such channel %s' % channel) pass if capability in conf.defaultCapabilities: - #debug.printf('capability in conf.defaultCapability') return True elif invertCapability(capability) in conf.defaultCapabilities: - #debug.printf('inverse capability in conf.defaultCapability') return False else: - #debug.printf('returning appropriate value given no good reason') return _x(capability, conf.defaultAllow) def checkCapability(hostmask, capability, users=users, channels=channels): """Checks that the user specified by name/hostmask has the capabilty given. """ - #debug.printf('*** checking %s for %s' % (hostmask, capability)) if world.startup: - #debug.printf('world.startup is active.') return _x(capability, True) try: u = users.getUser(hostmask) if u.secure and not u.checkHostmask(hostmask, useAuth=False): - #debug.printf('Secure user with non-matching hostmask.') raise KeyError except KeyError: # Raised when no hostmasks match. @@ -630,16 +620,13 @@ def checkCapability(hostmask, capability, users=users, channels=channels): channels=channels) except ValueError, e: # Raised when multiple hostmasks match. - debug.msg('%s: %s' % (hostmask, e)) + log.warning('%s: %s', hostmask, e) return _checkCapabilityForUnknownUser(capability, users=users, channels=channels) - #debug.printf('user found.') if capability in u.capabilities: - #debug.printf('found capability in u.capabilities.') return u.checkCapability(capability) else: if isChannelCapability(capability): - #debug.printf('isChannelCapability true, user found too.') (channel, capability) = fromChannelCapability(capability) try: chanop = makeChannelCapability(channel, 'op') @@ -649,19 +636,14 @@ def checkCapability(hostmask, capability, users=users, channels=channels): pass c = channels.getChannel(channel) if capability in c.capabilities: - #debug.printf('capability in c.capabilities') return c.checkCapability(capability) else: - #debug.printf('capability not in c.capabilities') return _x(capability, c.defaultAllow) if capability in conf.defaultCapabilities: - #debug.printf('capability in conf.defaultCapabilities') return True elif invertCapability(capability) in conf.defaultCapabilities: - #debug.printf('inverse capability in conf.defaultCapabilities') return False else: - #debug.printf('returning appropriate value given no good reason') return _x(capability, conf.defaultAllow) diff --git a/src/irclib.py b/src/irclib.py index b363077b5..590672f38 100644 --- a/src/irclib.py +++ b/src/irclib.py @@ -38,8 +38,8 @@ import sets import time from itertools import imap, chain +import log import conf -import debug import utils import world import ircdb @@ -102,10 +102,8 @@ class IrcCallback(IrcCommandDispatcher): try: method(irc, msg) except Exception, e: - debug.recoverableException() - s = 'Exception (%s) raised by %s.%s' % \ - (e, self.__class__.__name__, method.im_func.func_name) - debug.msg(s) + s = 'Exception caught in generic IrcCallback.__call__:' + log.exception(s) def reset(self): """Resets the callback. Called when reconnected to the server.""" @@ -151,7 +149,7 @@ class IrcMsgQueue(object): """Enqueues a given message.""" if msg in self.msgs: if not world.startup: - debug.msg('Not adding msg %s to queue' % msg, 'normal') + log.info('Not adding msg %s to queue' % msg) else: self.msgs.add(msg) if msg.command in _high: @@ -163,18 +161,19 @@ class IrcMsgQueue(object): def dequeue(self): """Dequeues a given message.""" + msg = None if self.highpriority: msg = self.highpriority.dequeue() elif self.normal: msg = self.normal.dequeue() elif self.lowpriority: msg = self.lowpriority.dequeue() - else: - msg = None if msg: - if msg not in self.msgs: - debug.msg('Odd, dequeuing a message that\'s not in self.msgs.') - self.msgs.discard(msg) + try: + self.msgs.remove(msg) + except KeyError: + s = 'Odd, dequeuing a message that\'s not in self.msgs.' + log.warning(s) return msg def __nonzero__(self): @@ -404,10 +403,10 @@ class Irc(IrcCommandDispatcher): '333', '353', '332', '366', '005']) def __init__(self, nick, user='', ident='', password='', callbacks=None): world.ircs.append(self) - self.nick = nick + self.nick = intern(nick) self.password = password - self.user = user or nick # Default to nick if user isn't provided. - self.ident = ident or nick # Ditto. + self.user = intern(user or nick) # Default to nick + self.ident = intern(ident or nick) # Ditto. self.prefix = '%s!%s@%s' % (nick, ident, 'unset.domain') if callbacks is None: self.callbacks = [] @@ -481,13 +480,14 @@ class Irc(IrcCommandDispatcher): msg = self.fastqueue.dequeue() elif self.queue: if not world.testing and now - self.lastTake <= conf.throttleTime: - debug.msg('Irc.takeMsg throttling.', 'verbose') + log.debug('Irc.takeMsg throttling.') else: self.lastTake = now msg = self.queue.dequeue() elif now > (self.lastping + conf.pingInterval): if self.outstandingPing: - debug.msg('Reconnecting, ping not replied to.', 'normal') + s = 'Reconnecting to %s, ping not replied to.' % self.server + log.warning(s) self.driver.reconnect() self.reset() else: @@ -497,7 +497,7 @@ class Irc(IrcCommandDispatcher): self.queueMsg(ircmsgs.ping(now)) if msg: for callback in reviter(self.callbacks): - #debug.printf(repr(msg)) + log.debug(repr(msg)) try: outFilter = getattr(callback, 'outFilter') except AttributeError, e: @@ -505,18 +505,18 @@ class Irc(IrcCommandDispatcher): try: msg = outFilter(self, msg) except: - debug.recoverableException() + log.exception('Exception caught in outFilter:') continue if msg is None: - s = '%s.outFilter returned None' % callback.name() - debug.msg(s) - return None + log.debug('%s.outFilter returned None' % callback.name()) + return self.takeMsg() if len(str(msg)) > 512: + # Yes, this violates the contract, but at this point it doesn't + # matter. That's why we gotta go munging in private attributes msg._str = msg._str[:500] + '\r\n' msg._len = len(str(msg)) self.state.addMsg(self, msg) - s = '%s %s' % (time.strftime(conf.logTimestampFormat), msg) - debug.msg(s, 'low') + log.info('Outgoing message: ' + str(msg).rstrip('\r\n')) if msg.command == 'NICK': # We don't want a race condition where the server's NICK # back to us is lost and someone else steals our nick and uses @@ -562,36 +562,31 @@ class Irc(IrcCommandDispatcher): def doNick(self, msg): """Handles NICK messages.""" if msg.nick == self.nick: - newNick = msg.args[0] + newNick = intern(msg.args[0]) user = ircdb.users.getUser(0) user.unsetAuth() user.hostmasks = [] try: ircdb.users.getUser(newNick) - s = 'User already registered with name %s' % newNick - debug.msg(s, 'high') + log.error('User already registered with name %s' % newNick) except KeyError: user.name = newNick ircdb.users.setUser(0, user) self.nick = newNick (nick, user, domain) = ircutils.splitHostmask(msg.prefix) self.prefix = ircutils.joinHostmask(self.nick, user, domain) + self.prefix = intern(self.prefix) def feedMsg(self, msg): """Called by the IrcDriver; feeds a message received.""" - debug.msg('%s %s'%(time.strftime(conf.logTimestampFormat), msg),'low') + log.info('Incoming message: ' + str(msg).rstrip('\r\n')) # Yeah, so this is odd. Some networks (oftc) seem to give us certain # messages with our nick instead of our prefix. We'll fix that here. if msg.prefix == self.nick: - debug.msg('Got one of those odd nick-instead-of-prefix msgs.') + log.debug('Got one of those odd nick-instead-of-prefix msgs.') msg = ircmsgs.IrcMsg(prefix=self.prefix, msg=msg) - # Dispatch to specific handlers for commands. - method = self.dispatchCommand(msg.command) - if method is not None: - method(msg) - # This catches cases where we know our own nick (from sending it to the # server) but we don't yet know our prefix. if msg.nick == self.nick and self.prefix != msg.prefix: @@ -610,32 +605,37 @@ class Irc(IrcCommandDispatcher): if msg.prefix != self.server: self.server = msg.prefix + # Dispatch to specific handlers for commands. + method = self.dispatchCommand(msg.command) + if method is not None: + method(msg) + # Now update the IrcState object. try: self.state.addMsg(self, msg) except: - debug.recoverableException() + log.exception('Exception in update of IrcState object:') # Now call the callbacks. for callback in self.callbacks: try: m = callback.inFilter(self, msg) if not m: - s = '%s.inFilter returned None' % callback.name() - debug.msg(s) + log.debug('%s.inFilter returned None' % callback.name()) return msg = m except: - debug.recoverableException() + log.exception('Uncaught exception in inFilter:') for callback in self.callbacks: try: if callback is not None: callback(self, msg) except: - debug.recoverableException() + log.exception('Uncaught exception in callback:') def die(self): """Makes the Irc object die. Dead.""" + log.info('Irc object for %s dying.' % self.server) for callback in self.callbacks: callback.die() if self.driver is not None: diff --git a/src/ircmsgs.py b/src/ircmsgs.py index 0f90fae5c..cd0df8635 100644 --- a/src/ircmsgs.py +++ b/src/ircmsgs.py @@ -43,7 +43,6 @@ import fix import re import string -import debug import ircutils ### @@ -124,13 +123,14 @@ class IrcMsg(object): else: self.args = msg.args else: - self.prefix = prefix - self.command = command + self.prefix = intern(prefix) + self.command = intern(command) assert all(ircutils.isValidArgument, args) self.args = args - self.args = tuple(self.args) + self.args = tuple(map(intern, self.args)) if ircutils.isUserHostmask(self.prefix): - (self.nick,self.user,self.host)=ircutils.splitHostmask(self.prefix) + (self.nick,self.user,self.host) = \ + map(intern, ircutils.splitHostmask(self.prefix)) else: (self.nick, self.user, self.host) = (self.prefix,)*3 diff --git a/src/ircutils.py b/src/ircutils.py index 09a696c0d..c9ad596b1 100644 --- a/src/ircutils.py +++ b/src/ircutils.py @@ -94,7 +94,7 @@ _lowertrans = string.maketrans(string.ascii_uppercase + r'\[]~', string.ascii_lowercase + r'|{}^') def toLower(s): """Returns the string s lowered according to IRC case rules.""" - return s.translate(_lowertrans) + return intern(s.translate(_lowertrans)) def nickEqual(nick1, nick2): """Returns True if nick1 == nick2 according to IRC case rules.""" @@ -329,7 +329,7 @@ def unDccIP(i): class IrcString(str): """This class does case-insensitive comparison and hashing of nicks.""" def __init__(self, s): - str.__init__(self, s) + str.__init__(self, intern(s)) self.lowered = toLower(s) def __eq__(self, s): diff --git a/src/log.py b/src/log.py new file mode 100644 index 000000000..1c716a68d --- /dev/null +++ b/src/log.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python + +### +# Copyright (c) 2002, Jeremiah Fincher +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions, and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions, and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author of this software nor the name of +# contributors to this software may be used to endorse or promote products +# derived from this software without specific prior written consent. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +### + +__revision__ = "$Id$" + +import fix + +import os +import sys +import atexit +import logging + +import conf + +deadlyExceptions = [KeyboardInterrupt, SystemExit] + +if not os.path.exists(conf.logDir): + os.mkdir(conf.logDir, 0755) + +pluginLogDir = os.path.join(conf.logDir, 'plugins') + +if not os.path.exists(pluginLogDir): + os.mkdir(pluginLogDir, 0755) + +class Formatter(logging.Formatter): + def formatTime(self, record, datefmt=None): + if datefmt is None: + datefmt = conf.logTimestampFormat + return logging.Formatter.formatTime(self, record, datefmt) + + def formatException(self, (E, e, tb)): + for exn in deadlyExceptions: + if issubclass(e.__class__, exn): + raise + ### TODO: formatException should use cgitb. + return logging.Formatter.formatException(self, (E, e, tb)) + +class DailyRotatingHandler(logging.FileHandler): + def __init__(self, *args): + self.lastRollover = time.localtime() + logging.FileHandler.__init__(self, *args) + + def emit(self, record): + now = time.localtime() + if now[2] != self.lastRollover[2]: + self.doRollover() + self.lastRollover = now + logging.FileHandler.emit(self, record) + + def doRollover(self): + self.stream.close() + extension = time.strftime('%d-%b-%Y', self.lastRollover) + os.rename(self.baseFilename, '%s.%s' % (self.baseFilename, extension)) + self.stream = file(self.baseFilename, 'w') + +# This is available publically. +formatter = Formatter('%(levelname)s %(asctime)s %(message)s') +pluginFormatter = Formatter('%(levelname)s %(asctime)s %(name)s %(message)s') + +# These are not. +_logger = logging.getLogger('supybot') +_handler = logging.FileHandler(os.path.join(conf.logDir, 'misc.log')) +_handler.setFormatter(formatter) +_handler.setLevel(conf.minimumLogPriority) +_logger.addHandler(_handler) +_logger.setLevel(-1) + +if conf.stdoutLogging: + _stdoutHandler = logging.StreamHandler(sys.stdout) + _stdoutHandler.setLevel(conf.minimumLogPriority) + _logger.addHandler(_stdoutHandler) + +debug = _logger.debug +info = _logger.info +warning = _logger.warning +error = _logger.error +critical = _logger.critical +exception = _logger.exception + +printf = curry(_logger.log, 1) +logging.PRINTF = 1 +logging._levelNames['PRINTF'] = logging.PRINTF +logging._levelNames[logging.PRINTF] = 'PRINTF' + +verbose = curry(_logger.log, 5) +logging.VERBOSE = 5 +logging._levelNames['VERBOSE'] = logging.VERBOSE +logging._levelNames[logging.VERBOSE] = 'VERBOSE' + +atexit.register(logging.shutdown) + +def getPluginLogger(name): + log = logging.getLogger('supybot.plugins.%s' % name) + if not log.handlers: + filename = os.path.join(pluginLogDir, '%s.log' % name) + handler = logging.FileHandler(filename) + handler.setLevel(conf.minimumLogPriority) + handler.setFormatter(pluginFormatter) + log.addHandler(handler) + return log + + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: + diff --git a/src/plugins.py b/src/plugins.py index d73d16f1e..7bf35c341 100644 --- a/src/plugins.py +++ b/src/plugins.py @@ -49,7 +49,6 @@ __revision__ = "$Id$" import fix import cdb import conf -import debug import utils import world import ircdb @@ -203,8 +202,7 @@ class PeriodicFileDownloader(object): s = infd.read(4096) infd.close() outfd.close() - msg = 'Downloaded %s in %s seconds' % (filename, time.time() - start) - debug.msg(msg, 'verbose') + self.log.info('Downloaded %s in %s seconds',filename,time.time()-start) self.downloadedCounter[filename] += 1 self.lastDownloaded[filename] = time.time() if f is None: @@ -218,15 +216,14 @@ class PeriodicFileDownloader(object): start = time.time() f(newFilename) total = time.time() - start - msg = 'Function ran on %s in %s seconds' % (filename, total) - debug.msg(msg, 'verbose') + self.log.info('Function ran on %s in %s seconds', filename, total) self.currentlyDownloading.remove(filename) def getFile(self, filename): (url, timeLimit, f) = self.periodicFiles[filename] if time.time() - self.lastDownloaded[filename] > timeLimit and \ filename not in self.currentlyDownloading: - debug.msg('Beginning download of %s' % url, 'verbose') + self.log.info('Beginning download of %s', url) self.currentlyDownloading.add(filename) args = (filename, url, f) name = '%s #%s' % (filename, self.downloadedCounter[filename]) @@ -345,12 +342,11 @@ class Configurable(object): try: self.configurables.set(name, eval(value), channel) except ConfigurableTypeError, e: - name = '%s.%s' % (self.__class__.__name__, name) - s = 'Couldn\'t read configurable %s from file: %s'%(name,e) - debug.msg(s) + s = 'Couldn\'t read configurable from file: %s' + self.log.warning(s, e) except KeyError, e: - s = 'Configurable variable %s doesn\'t exist anymore'%name - debug.msg(s) + s = 'Configurable variable %s doesn\'t exist anymore.' + self.log.warning(s, name) def die(self): fd = file(self.filename, 'w') diff --git a/src/privmsgs.py b/src/privmsgs.py index 92b704ae5..c8f840e73 100644 --- a/src/privmsgs.py +++ b/src/privmsgs.py @@ -42,7 +42,6 @@ import types import threading import conf -import debug import ircdb import world import ircutils @@ -166,14 +165,12 @@ def urlSnarfer(f): if q is None: q = structures.smallqueue() self._snarfedUrls = q - #debug.printf('before pruning: %r' % q) while q and q[0][2] < cutoff: q.dequeue() - #debug.printf('after pruning: %r' % q) url = match.group(0) if any(lambda t: t[0] == url and t[1] == msg.args[0], q) and \ not world.testing: - debug.msg('Refusing to snarf %s.' % url) + self.log.warning('Refusing to snarf %s.', url) else: q.enqueue((url, msg.args[0], now)) if self.threaded: diff --git a/src/repl.py b/src/repl.py index 31e3a89cb..be511deee 100644 --- a/src/repl.py +++ b/src/repl.py @@ -39,7 +39,7 @@ import sys import traceback from cStringIO import StringIO -import debug +import log filename = 'repl' @@ -86,7 +86,7 @@ class Repl(object): line = line.rstrip() self.lines.append(line) if len(self.lines) > 100: - debug.msg('too many lines in Repl.', 'normal') + log.warning('Too many lines in Repl.') self.lines = [] return None if line == '' or line == '\n' or line == '\r\n': diff --git a/src/schedule.py b/src/schedule.py index c5aaa7cd5..a7fa11c30 100644 --- a/src/schedule.py +++ b/src/schedule.py @@ -76,7 +76,6 @@ class Schedule(drivers.IrcDriver): self.counter += 1 elif isinstance(name, int): raise ValueError, 'int names are reserved for the scheduler.' - #debug.printf('Added event to schedule: %s' % name) assert name not in self.events self.events[name] = f heapq.heappush(self.schedule, mytuple((t, name))) @@ -97,7 +96,6 @@ class Schedule(drivers.IrcDriver): removePeriodicEvent = removeEvent def run(self): - #debug.printf(`(time.time(), self.schedule)`) while self.schedule and self.schedule[0][0] < time.time(): (t, name) = heapq.heappop(self.schedule) f = self.events[name] diff --git a/src/socketDrivers.py b/src/socketDrivers.py index dc0fb2566..81d899b75 100644 --- a/src/socketDrivers.py +++ b/src/socketDrivers.py @@ -35,7 +35,7 @@ Contains simple socket drivers. Asyncore bugged (haha, pun!) me. from __future__ import division -__revision__ = "$Id$" +__revision__ ="$Id$" import fix @@ -43,8 +43,8 @@ import time import socket from itertools import imap +import log import conf -import debug import drivers import ircmsgs import schedule @@ -69,7 +69,6 @@ class SocketDriver(drivers.IrcDriver): self.reconnect() def _sendIfMsgs(self): - #debug.methodNamePrintf(self, '_sendIfMsgs') msgs = [self.irc.takeMsg()] while msgs[-1] is not None: msgs.append(self.irc.takeMsg()) @@ -83,12 +82,10 @@ class SocketDriver(drivers.IrcDriver): # (11, 'Resource temporarily unavailable') raised if connect # hasn't finished yet. if e.args[0] != 11: - s = 'Disconnect from %s: %s' % (self.server, e.args[1]) - debug.msg(s, 'normal') + log.warning('Disconnect from %s: %s',self.server,e.args[1]) self.die() def run(self): - #debug.methodNamePrintf(self, 'run') if not self.connected: time.sleep(conf.poll) # Otherwise we might spin. return @@ -100,26 +97,22 @@ class SocketDriver(drivers.IrcDriver): for line in lines: start = time.time() msg = ircmsgs.IrcMsg(line) - debug.msg('Time to parse IrcMsg: %s' % (time.time()-start), - 'verbose') + log.verbose('Time to parse IrcMsg: %s', time.time()-start) try: self.irc.feedMsg(msg) except: - debug.msg('Exception caught outside Irc object.', 'normal') - debug.recoverableException() + log.exception('Uncaught exception outside Irc object:') except socket.timeout: pass except socket.error, e: # Same as with _sendIfMsgs. if e.args[0] != 11: - s = 'Disconnect from %s: %s' % (self.server, e.args[1]) - debug.msg(s, 'normal') + log.warning('Disconnect from %s: %s', self.server, e.args[1]) self.die() return self._sendIfMsgs() def reconnect(self): - #debug.methodNamePrintf(self, 'reconnect') self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.conn.settimeout(conf.poll*10) # Allow more time for connect. if self.reconnectWaitsIndex < len(self.reconnectWaits)-1: @@ -129,21 +122,19 @@ class SocketDriver(drivers.IrcDriver): self.conn.settimeout(conf.poll) except socket.error, e: if e.args[0] != 115: - debug.msg('Error connecting to %s: %s' % (self.server, e)) + log.warning('Error connecting to %s: %s', self.server, e) self.die() self.connected = True self.reconnectWaitPeriodsIndex = 0 def die(self): - #debug.methodNamePrintf(self, 'die') self.irc.reset() self.conn.close() self.connected = False when = time.time() + self.reconnectWaits[self.reconnectWaitsIndex] whenS = time.strftime(conf.logTimestampFormat, time.localtime(when)) - debug.msg('Scheduling reconnect to %s at %s' % (self.server, whenS), - 'normal') + log.info('Scheduling reconnect to %s at %s', self.server, whenS) schedule.addEvent(self.reconnect, when) def name(self): diff --git a/src/template.py b/src/template.py index fd6e6477a..7bd85da15 100755 --- a/src/template.py +++ b/src/template.py @@ -56,6 +56,7 @@ started = time.time() import supybot +import log import conf defaultNick = "%%nick%%" @@ -68,7 +69,6 @@ conf.commandsOnStart = "%%onStart%%" afterConnect = "%%afterConnect%%" -debugVariables = "%%debugVariables%%" configVariables = "%%configVariables%%" if not isinstance(configVariables, basestring): @@ -77,17 +77,9 @@ if not isinstance(configVariables, basestring): if not os.path.exists(conf.dataDir): os.mkdir(conf.dataDir) -if not os.path.exists(conf.logDir): - os.mkdir(conf.logDir) if not os.path.exists(conf.confDir): os.mkdir(conf.confDir) -import debug - -if not isinstance(debugVariables, basestring): - for (name, value) in debugVariables.iteritems(): - setattr(debug, name, value) - def main(): import world import drivers @@ -97,11 +89,10 @@ def main(): try: while world.ircs: drivers.run() + except (SystemExit, KeyboardInterrupt): + sys.exit(0) except: - try: - debug.recoverableException() - except: # It must've been deadly for a reason :) - sys.exit(0) + log.exception('Exception raised out of drivers.run:') if __name__ == '__main__': ### diff --git a/src/twistedDrivers.py b/src/twistedDrivers.py index 23193f088..07d16a2ae 100644 --- a/src/twistedDrivers.py +++ b/src/twistedDrivers.py @@ -35,8 +35,8 @@ import fix import time +import log import conf -import debug import ircdb import drivers import ircmsgs @@ -51,8 +51,7 @@ class TwistedRunnerDriver(drivers.IrcDriver): try: reactor.iterate(conf.poll) except: - debug.msg('Except caught outside reactor.', 'normal') - debug.recoverableException() + log.exception('Uncaught exception outside reactor:') class SupyIrcProtocol(LineReceiver): delimiter = '\n' @@ -63,12 +62,11 @@ class SupyIrcProtocol(LineReceiver): def lineReceived(self, line): start = time.time() msg = ircmsgs.IrcMsg(line) - debug.msg('Time to parse IrcMsg: %s' % (time.time()-start), 'verbose') + log.verbose('Time to parse IrcMsg: %s', time.time()-start) try: self.factory.irc.feedMsg(msg) except: - debug.msg('Exception caught outside Irc object.', 'normal') - debug.recoverableException() + log.exception('Uncaught exception outside Irc object:') def checkIrcForMsgs(self): if self.connected: @@ -80,7 +78,7 @@ class SupyIrcProtocol(LineReceiver): def connectionLost(self, failure): self.mostRecentCall.cancel() self.factory.irc.reset() - debug.msg(failure.getErrorMessage(), 'normal') + log.warning(failure.getErrorMessage()) def connectionMade(self): self.factory.irc.driver = self @@ -105,14 +103,10 @@ class SupyReconnectingFactory(ReconnectingClientFactory): class MyShell(Shell): def checkUserAndPass(self, username, password): - #debug.printf(repr(username)) - #debug.printf(repr(password)) try: id = ircdb.users.getUserId(username) u = ircdb.users.getUser(id) - #debug.printf(u) if u.checkPassword(password) and u.checkCapability('owner'): - #debug.printf('returning True') return True else: return False diff --git a/src/utils.py b/src/utils.py index e71396c12..ca9ab4132 100755 --- a/src/utils.py +++ b/src/utils.py @@ -456,8 +456,11 @@ def safeEval(s, namespace={'True': True, 'False': False, 'None': None}): return eval(s, namespace, namespace) else: raise ValueError, 'Unsafe string.' - - + + +def exnToString(e): + """Turns a simple exception instance into a string (better than str(e))""" + return '%s: %s' % (e.__class__.__name__, e) class IterableMap(object): """Define .iteritems() in a class and subclass this to get the other iters. diff --git a/src/world.py b/src/world.py index 02b231145..f3101e212 100644 --- a/src/world.py +++ b/src/world.py @@ -45,8 +45,8 @@ import types import atexit import threading +import log import conf -import debug startedAt = 0.0 @@ -83,12 +83,11 @@ def upkeep(): # Function to be run on occasion to do upkeep stuff. except IOError: # Win98 sux0rs! pass if gc.garbage: - debug.msg('Uncollectable garbage: %s' % gc.garbage, 'normal') + log.warning('Uncollectable garbage: %s', gc.garbage) if 'noflush' not in tempvars: flush() - debug.msg('Regexp cache size: %s' % len(sre._cache), 'verbose') - msg = '%s upkeep ran.' % time.strftime(conf.logTimestampFormat) - debug.msg(msg, 'verbose') + log.verbose('Regexp cache size: %s', len(sre._cache)) + log.info('%s upkeep ran.', time.strftime(conf.logTimestampFormat)) return collected def makeIrcsDie(): diff --git a/test/test.py b/test/test.py index 46a78643a..49ce0928b 100755 --- a/test/test.py +++ b/test/test.py @@ -49,8 +49,6 @@ started = time.time() import os.path import unittest -import debug - import world world.startedAt = started import ircdb @@ -134,7 +132,6 @@ class PluginTestCase(unittest.TestCase): if self.cleanDataDir: for filename in os.listdir(conf.dataDir): os.remove(os.path.join(conf.dataDir, filename)) - debug.reset() ircdb.users.reload() ircdb.channels.reload() if self.plugins is None: @@ -166,7 +163,6 @@ class PluginTestCase(unittest.TestCase): if self.myVerbose: print # Extra newline, so it's pretty. msg = ircmsgs.privmsg(self.irc.nick, query, prefix=self.prefix) - #debug.printf(msg) if self.myVerbose: print 'Feeding: %r' % msg self.irc.feedMsg(msg) @@ -370,10 +366,14 @@ if __name__ == '__main__': if not os.path.exists(conf.logDir): os.mkdir(conf.logDir) - debug._close() for filename in os.listdir(conf.logDir): - os.remove(os.path.join(conf.logDir, filename)) - debug._open() + if filename == 'plugins': + continue + filename = os.path.join(conf.logDir, filename) + os.remove(filename) + pluginLogDir = os.path.join(conf.logDir, 'plugins') + for filename in os.listdir(pluginLogDir): + os.remove(os.path.join(pluginLogDir, filename)) parser = optparse.OptionParser(usage='Usage: %prog [options]', version='Supybot %s' % conf.version) @@ -390,9 +390,6 @@ if __name__ == '__main__': parser.add_option('-v', '--verbose', action='store_true', default=False, help='Sets the verbose flag, printing extra information ' 'about each test that runs.') - parser.add_option('-s', '--stderr', action='store_true', default=False, - help='Sets debug.stderr to True, printing standard log ' - 'messages to stderr.') (options, args) = parser.parse_args() if not args: args = map(path, glob.glob(os.path.join('test', 'test_*.py'))) @@ -414,11 +411,6 @@ if __name__ == '__main__': else: world.myVerbose = False - if options.stderr: - debug.stderr = True - else: - debug.stderr = False - world.testing = True names = [os.path.splitext(os.path.basename(name))[0] for name in args] names.sort() @@ -427,6 +419,5 @@ if __name__ == '__main__': runner.run(suite) print 'Total asserts: %s' % unittest.asserts world.testing = False - debug._close() # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/test/test_Misc.py b/test/test_Misc.py index 554083ac7..a46f8f948 100644 --- a/test/test_Misc.py +++ b/test/test_Misc.py @@ -111,7 +111,6 @@ class MiscTestCase(ChannelPluginTestCase, PluginDocumentation): def testTell(self): m = self.getMsg('tell foo [plugin tell]') - #debug.printf(repr(m)) self.failUnless(m.args[0] == 'foo') self.failUnless('Misc' in m.args[1]) m = self.getMsg('tell #foo [plugin tell]') @@ -152,6 +151,9 @@ class MiscTestCase(ChannelPluginTestCase, PluginDocumentation): self.assertNotError('apropos f') self.assertError('apropos asldkfjasdlkfja') + def testAproposDoesntReturnNonCanonicalNames(self): + self.assertNotRegexp('apropos exec', '_exec') + def testRevision(self): self.assertNotError('revision Misc') self.assertNotError('revision') diff --git a/test/test_Owner.py b/test/test_Owner.py index f4f8b3292..4db836414 100644 --- a/test/test_Owner.py +++ b/test/test_Owner.py @@ -72,10 +72,6 @@ class OwnerTestCase(PluginTestCase, PluginDocumentation): finally: conf.allowEval = originalConfAllowEval - def testSettrace(self): - self.assertNotError('settrace') - self.assertNotError('unsettrace') - def testIrcquote(self): self.assertResponse('ircquote PRIVMSG %s :foo' % self.irc.nick, 'foo') diff --git a/test/test_Sourceforge.py b/test/test_Sourceforge.py index 8fc4b0e51..48323c1b5 100644 --- a/test/test_Sourceforge.py +++ b/test/test_Sourceforge.py @@ -38,6 +38,7 @@ class SourceforgeTest(ChannelPluginTestCase, PluginDocumentation): def testBug(self): self.assertHelp('bug') m = self.getMsg('bugs gaim') + self.failUnless(m, 'No response from Sourceforge.') n = re.search('#(\d+)', m.args[1]).group(1) self.assertNotError('bug gaim %s' % n) self.assertError('bug gaim') @@ -54,6 +55,7 @@ class SourceforgeTest(ChannelPluginTestCase, PluginDocumentation): def testRfe(self): m = self.getMsg('rfes gaim') + self.failUnless(m, 'No response from Sourceforge.') n = re.search('#(\d+)', m.args[1]).group(1) self.assertNotError('rfe gaim %s' % n) self.assertError('rfe gaim') diff --git a/test/test_ircdb.py b/test/test_ircdb.py index 0875054ca..de1908d89 100644 --- a/test/test_ircdb.py +++ b/test/test_ircdb.py @@ -35,7 +35,6 @@ import os import unittest import conf -import debug import ircdb import ircutils diff --git a/test/test_irclib.py b/test/test_irclib.py index ba6887d3f..6987e741f 100644 --- a/test/test_irclib.py +++ b/test/test_irclib.py @@ -35,7 +35,6 @@ import copy import pickle import conf -import debug import irclib import ircmsgs @@ -81,7 +80,7 @@ class IrcMsgQueueTestCase(unittest.TestCase): try: repr(q) except Exception, e: - self.fail('repr(q) raised an exception: %s' % debug.exnToString(e)) + self.fail('repr(q) raised an exception: %s' % utils.exnToString(e)) def testEmpty(self): q = irclib.IrcMsgQueue() diff --git a/test/test_schedule.py b/test/test_schedule.py index 4323c20ac..e75bef927 100644 --- a/test/test_schedule.py +++ b/test/test_schedule.py @@ -33,7 +33,6 @@ from test import * import time -import debug import schedule class TestSchedule(unittest.TestCase):