This commit is contained in:
Jeremy Fincher 2004-04-13 05:18:17 +00:00
parent e32b66df93
commit 132adeff7d
2 changed files with 62 additions and 42 deletions

View File

@ -31,7 +31,7 @@
### ###
""" """
Allows for sending the bot's logging output to channels. Allows for sending the bot's logging output to a channel.
""" """
__revision__ = "$Id$" __revision__ = "$Id$"
@ -44,6 +44,7 @@ import log
import conf import conf
import utils import utils
import world import world
import ircmsgs
import ircutils import ircutils
import privmsgs import privmsgs
import registry import registry
@ -51,26 +52,24 @@ import callbacks
class IrcHandler(logging.Handler): class IrcHandler(logging.Handler):
def __init__(self, irc=None):
logging.Handler.__init__(self)
self._irc = irc
def emit(self, record): def emit(self, record):
channel = conf.supybot.plugins.LogToChannel.channel()
try: try:
if not self._irc.driver.connected: s = utils.normalizeWhitespace(self.format(record))
return except:
except AttributeError: self.handleError(record)
return msg = ircmsgs.privmsg(channel, s)
from ircmsgs import privmsg if channel:
for channel in conf.supybot.plugins.LogToChannel.channels(): for irc in world.ircs:
try: try:
msg = self.format(record).split('\n') if not irc.driver.connected:
msg = [line.strip() for line in msg] continue
msg = ' '.join(msg) except AttributeError, e:
self._irc.queueMsg(privmsg(channel, msg)) print '*** AttributeError, shouldn\'t happen: %s' % e
except: continue
self.handleError(record) if channel in irc.state.channels:
irc.queueMsg(msg)
class IrcFormatter(log.Formatter): class IrcFormatter(log.Formatter):
def formatException(self, ei): def formatException(self, ei):
@ -93,51 +92,62 @@ class ColorizedIrcFormatter(IrcFormatter):
return IrcFormatter.formatException(self, (E, e, tb)) return IrcFormatter.formatException(self, (E, e, tb))
def format(self, record, *args, **kwargs): def format(self, record, *args, **kwargs):
s = IrcFormatter.format(self, record, *args, **kwargs)
if conf.supybot.plugins.LogToChannel.colorized(): if conf.supybot.plugins.LogToChannel.colorized():
fmt = '%s'
if record.levelno == logging.CRITICAL: if record.levelno == logging.CRITICAL:
fmt = ircutils.bold(ircutils.mircColor('%s', fg='red')) s = ircutils.bold(ircutils.mircColor(s, fg='red'))
elif record.levelno == logging.ERROR: elif record.levelno == logging.ERROR:
fmt = ircutils.mircColor('%s', fg='red') s = ircutils.mircColor(s, fg='orange')
elif record.levelno == logging.WARNING: elif record.levelno == logging.WARNING:
fmt = ircutils.mircColor('%s', fg='orange') s = ircutils.mircColor(s, fg='yellow')
return fmt % IrcFormatter.format(self, record, *args, **kwargs) return s
else:
return IrcFormatter.format(self, record, *args, **kwargs)
_ircHandler = IrcHandler(irc=world.ircs[0]) _ircHandler = IrcHandler()
_formatString = '%(name)s: %(levelname)s %(message)s' _formatString = '%(name)s: %(levelname)s %(message)s'
_ircFormatter = ColorizedIrcFormatter(_formatString) _ircFormatter = ColorizedIrcFormatter(_formatString)
_ircHandler.setFormatter(_ircFormatter) _ircHandler.setFormatter(_ircFormatter)
class ChannelLogLevel(log.LogLevel):
"""Invalid log level. Value must be either INFO, WARNING, ERROR,
or CRITICAL."""
def setValue(self, v):
if v <= logging.DEBUG:
self.error()
else:
log.LogLevel.setValue(self, v)
_ircHandler.setLevel(v)
class ValidChannelOrNot(conf.ValidChannel):
def setValue(self, v):
if v:
conf.ValidChannel.setValue(self, v)
else:
registry.Value.setValue(self, '')
conf.registerPlugin('LogToChannel') conf.registerPlugin('LogToChannel')
conf.registerGlobalValue(conf.supybot.plugins.LogToChannel, 'level', conf.registerGlobalValue(conf.supybot.plugins.LogToChannel, 'level',
log.LogLevel(_ircHandler, logging.WARNING, """Determines what the minimum ChannelLogLevel(logging.WARNING, """Determines what the minimum priority
priority level logged will be to IRC. See supybot.log.level for possible level logged will be to IRC. See supybot.log.level for possible
values. (NEVER set this to DEBUG!)""")) values. DEBUG is disabled due to the large quantity of output."""))
conf.supybot.plugins.LogToChannel.level._target = _ircHandler conf.registerGlobalValue(conf.supybot.plugins.LogToChannel, 'channel',
_ircHandler.setLevel(conf.supybot.plugins.LogToChannel.level()) ValidChannelOrNot('', """Determines which channel the bot should log to or
conf.registerGlobalValue(conf.supybot.plugins.LogToChannel, 'channels', empty if none at all."""))
conf.SpaceSeparatedSetOfChannels('', """Determines which channels the
bot should log to or empty if none at all."""))
conf.registerGlobalValue(conf.supybot.plugins.LogToChannel, 'colorized', conf.registerGlobalValue(conf.supybot.plugins.LogToChannel, 'colorized',
registry.Boolean(False, """Determines whether the bot's logs registry.Boolean(False, """Determines whether the bot's logs
to IRC will be colorized with mIRC colors.""")) to IRC will be colorized with mIRC colors."""))
def configure(advanced): def configure(advanced):
from questions import something, anything, yn, output from questions import something, anything, yn, output
channels = '' channel = ''
while not channels: while not channel:
try: try:
channels = anything('Which channels would you like to send log ' channel = anything('Which channel would you like to send log '
'messages too?') 'messages too?')
conf.supybot.plugins.LogToChannel.channels.set(channels) conf.supybot.plugins.LogToChannel.channel.set(channel)
except registry.InvalidRegistryValue, e: except registry.InvalidRegistryValue, e:
output(str(e)) output(str(e))
channels = '' channel = ''
colorized = yn('Would you like these messages to be colored?') colorized = yn('Would you like these messages to be colored?')
conf.supybot.plugins.LogToChannel.colorized.setValue(colorized) conf.supybot.plugins.LogToChannel.colorized.setValue(colorized)
if advanced: if advanced:
@ -161,6 +171,11 @@ class LogToChannel(callbacks.Privmsg):
def die(self): def die(self):
log._logger.removeHandler(_ircHandler) log._logger.removeHandler(_ircHandler)
def do376(self, irc, msg):
channel = self.registryValue('channel')
if channel:
irc.queueMsg(ircmsgs.join(channel))
Class = LogToChannel Class = LogToChannel

View File

@ -100,10 +100,11 @@ def toLower(s):
"""Returns the string s lowered according to IRC case rules.""" """Returns the string s lowered according to IRC case rules."""
return intern(s.translate(_lowertrans)) return intern(s.translate(_lowertrans))
def nickEqual(nick1, nick2): def strEqual(nick1, nick2):
"""Returns True if nick1 == nick2 according to IRC case rules.""" """Returns True if nick1 == nick2 according to IRC case rules."""
return toLower(nick1) == toLower(nick2) return toLower(nick1) == toLower(nick2)
nickEqual = strEqual
_nickchars = r'_[]\`^{}|-' _nickchars = r'_[]\`^{}|-'
nickRe = re.compile(r'^[A-Za-z%s][0-9A-Za-z%s]*$' nickRe = re.compile(r'^[A-Za-z%s][0-9A-Za-z%s]*$'
@ -289,6 +290,10 @@ def mircColor(s, fg=None, bg=None):
"""Returns s with the appropriate mIRC color codes applied.""" """Returns s with the appropriate mIRC color codes applied."""
if fg is None and bg is None: if fg is None and bg is None:
return s return s
if isinstance(fg, int):
fg = mircColors[fg] # Convert to string, just in case.
if isinstance(bg, int):
bg = mircColors[bg] # Convert to string, just in case.
if fg is None or isinstance(fg, str): if fg is None or isinstance(fg, str):
fg = mircColors[fg] fg = mircColors[fg]
if bg is None: if bg is None: