Merge the changes from the python25compat branch into the trunk

This commit is contained in:
James Vega 2007-10-22 17:48:49 +00:00
parent b24eedf596
commit 7bb3b1ec60
10 changed files with 82 additions and 17 deletions

View File

@ -1,3 +1,60 @@
2007-10-22 James Vega <jamessan@supybot.com>
* Version 0.83.3!
* Added the BadWords plugin from supybot-plugins and updated the
plugin to allow kicking of people who use defined BadWords.
* Added support for different log levels on stdout vs the log file.
* Fixed a bug where the bot always reacted to invalid command floods
even if supybot.abuse.flood.command.invalid indicated not to.
(Closes: #1716878)
* Fixed a bug where the RSS plugin would lower-case URLs, thus making
them impossible to retrieve. (Closes: #1666786)
* Fixed ircmsgs.prettyPrint to handle unrecognized commands.
(Closes: #1630963)
* Fixed a bug in the Services plugin where the bot would continuously
send Ghost commands.
* Fixed Google.calc to handle a change in Google's HTML.
* Fixed a bug where Plugin.list was listing functions which weren't
valid commands.
* Fixed RSS's handling of encodings to eliminate some ascii conversion
errors.
* Updated the rssparser using plugins with the renamed and newer
feedparser 4.1 in order to properly handle Bugzilla RSS feeds.
* Updated PLUGIN_TUTORIAL to specify that the user needs to import
Python's random module.
* Updated the Web plugin so it uses HTMLParser over sgmllib's parser
since sgmllib's enters an infinite loop on invalid input.
* Updated getHelp() so callers can pass in the help string. This is
used in the Factoids plugin to dynamically generate a help string
based on a config value.
* Updated questions.py so bolding is handled better. User input,
default values, and defined choices are no longer bolded.
* Updated String.len to use wrap(). This greatly simplifies the
command and introduces better argument handling.
* Updated a few uses of sre to use re if the bot is running under
Python 2.5.
* Fixed test cases for mircColor and sorted (thanks dcraven).
* Updated assertAction's error message to give useful information
about what went wrong.
2006-07-23 James Vega <jamessan@supybot.com> 2006-07-23 James Vega <jamessan@supybot.com>
* Version 0.83.2! (A long overdue bugfix release) * Version 0.83.2! (A long overdue bugfix release)

View File

@ -1,3 +1,9 @@
Version 0.83.3
Overdue bug fix and Python2.5-compatible release. No significant changes to
worry about from the user perspective.
Version 0.83.2 Version 0.83.2
Mainly bug fix release. The most noticeable change being a value of Mainly bug fix release. The most noticeable change being a value of

View File

@ -63,6 +63,7 @@ class Misc(callbacks.Plugin):
maximum = conf.supybot.abuse.flood.command.invalid.maximum() maximum = conf.supybot.abuse.flood.command.invalid.maximum()
self.invalidCommands.enqueue(msg) self.invalidCommands.enqueue(msg)
if self.invalidCommands.len(msg) > maximum and \ if self.invalidCommands.len(msg) > maximum and \
conf.supybot.abuse.flood.command.invalid() and \
not ircdb.checkCapability(msg.prefix, 'owner'): not ircdb.checkCapability(msg.prefix, 'owner'):
punishment = conf.supybot.abuse.flood.command.invalid.punishment() punishment = conf.supybot.abuse.flood.command.invalid.punishment()
banmask = '*!%s@%s' % (msg.user, msg.host) banmask = '*!%s@%s' % (msg.user, msg.host)

View File

@ -40,7 +40,7 @@ def configure(advanced):
conf.registerPlugin('RSS', True) conf.registerPlugin('RSS', True)
class AnnouncedFeeds(registry.SpaceSeparatedListOfStrings): class FeedNames(registry.SpaceSeparatedListOfStrings):
List = callbacks.CanonicalNameSet List = callbacks.CanonicalNameSet
RSS = conf.registerPlugin('RSS') RSS = conf.registerPlugin('RSS')
@ -55,15 +55,15 @@ conf.registerChannelValue(RSS, 'announcementPrefix',
is prepended (if any) to the new news item announcements made in the is prepended (if any) to the new news item announcements made in the
channel.""")) channel."""))
conf.registerChannelValue(RSS, 'announce', conf.registerChannelValue(RSS, 'announce',
AnnouncedFeeds([], """Determines which RSS feeds should be announced in the registry.SpaceSeparatedSetOfStrings([], """Determines which RSS feeds
channel; valid input is a list of strings (either registered RSS feeds or should be announced in the channel; valid input is a list of strings
RSS feed URLs) separated by spaces.""")) (either registered RSS feeds or RSS feed URLs) separated by spaces."""))
conf.registerGlobalValue(RSS, 'waitPeriod', conf.registerGlobalValue(RSS, 'waitPeriod',
registry.PositiveInteger(1800, """Indicates how many seconds the bot will registry.PositiveInteger(1800, """Indicates how many seconds the bot will
wait between retrieving RSS feeds; requests made within this period will wait between retrieving RSS feeds; requests made within this period will
return cached results.""")) return cached results."""))
conf.registerGlobalValue(RSS, 'feeds', conf.registerGlobalValue(RSS, 'feeds',
AnnouncedFeeds([], """Determines what feeds should be accessible as FeedNames([], """Determines what feeds should be accessible as
commands.""")) commands."""))
conf.registerChannelValue(RSS, 'showLinks', conf.registerChannelValue(RSS, 'showLinks',
registry.Boolean(False, """Determines whether the bot will list the link registry.Boolean(False, """Determines whether the bot will list the link

View File

@ -416,11 +416,11 @@ class RSS(callbacks.Plugin):
when = 'time unavailable' when = 'time unavailable'
title = conv(info.get('title', 'unavailable')) title = conv(info.get('title', 'unavailable'))
desc = conv(info.get('description', 'unavailable')) desc = conv(info.get('description', 'unavailable'))
link = conv(info.get('link', 'unavailable'))
# The rest of the entries are all available in the channel key # The rest of the entries are all available in the channel key
response = format('Title: %s; URL: %u; ' response = format('Title: %s; URL: %u; '
'Description: %s; Last updated: %s.', 'Description: %s; Last updated: %s.',
title, info.get('link', 'unavailable').strip(), title, link, desc, when)
desc, when)
irc.reply(utils.str.normalizeWhitespace(response)) irc.reply(utils.str.normalizeWhitespace(response))
info = wrap(info, [first('url', 'feedName')]) info = wrap(info, [first('url', 'feedName')])

View File

@ -123,7 +123,7 @@ def main():
log.info('Total CPU time taken: %s seconds.', user+system) log.info('Total CPU time taken: %s seconds.', user+system)
log.info('No more Irc objects, exiting.') log.info('No more Irc objects, exiting.')
version = '0.83.2+darcs' version = '0.83.3'
if __name__ == '__main__': if __name__ == '__main__':
### ###
# Options: # Options:

View File

@ -151,7 +151,7 @@ package_dir = {'supybot': 'src',
for plugin in plugins: for plugin in plugins:
package_dir['supybot.plugins.' + plugin] = 'plugins/' + plugin package_dir['supybot.plugins.' + plugin] = 'plugins/' + plugin
version = '0.83.2+darcs' version = '0.83.3'
setup( setup(
# Metadata # Metadata
name='supybot', name='supybot',

View File

@ -43,7 +43,7 @@ _pluginsDir = os.path.join(installDir, 'plugins')
### ###
# version: This should be pretty obvious. # version: This should be pretty obvious.
### ###
version = '0.83.2+darcs' version = '0.83.3'
### ###
# *** The following variables are affected by command-line options. They are # *** The following variables are affected by command-line options. They are

View File

@ -171,7 +171,7 @@ class IrcMsg(object):
self.prefix == other.prefix and \ self.prefix == other.prefix and \
self.args == other.args self.args == other.args
__req__ = __eq__ # I don't know exactly what this does, but it can't hurt. __req__ = __eq__ # I don't know exactly what this does, but it can't hurt.
def __ne__(self, other): def __ne__(self, other):
return not (self == other) return not (self == other)
__rne__ = __ne__ # Likewise as above. __rne__ = __ne__ # Likewise as above.
@ -317,6 +317,8 @@ def prettyPrint(msg, addRecipients=False, timestampFormat=None, showNick=True):
s = '*** %s changes topic to %s' % (nickorprefix(), msg.args[1]) s = '*** %s changes topic to %s' % (nickorprefix(), msg.args[1])
elif msg.command == 'NICK': elif msg.command == 'NICK':
s = '*** %s is now known as %s' % (msg.nick, msg.args[0]) s = '*** %s is now known as %s' % (msg.nick, msg.args[0])
else:
s = utils.str.format('--- Unknown command %q', ' '.join(msg.args))
at = getattr(msg, 'receivedAt', None) at = getattr(msg, 'receivedAt', None)
if timestampFormat and at: if timestampFormat and at:
s = '%s %s' % (time.strftime(timestampFormat, time.localtime(at)), s) s = '%s %s' % (time.strftime(timestampFormat, time.localtime(at)), s)

View File

@ -204,6 +204,7 @@ _stdoutHandler = StdoutStreamHandler(sys.stdout)
class ValidLogLevel(registry.String): class ValidLogLevel(registry.String):
"""Invalid log level.""" """Invalid log level."""
handler = None
minimumLevel = -1 minimumLevel = -1
def set(self, s): def set(self, s):
s = s.upper() s = s.upper()
@ -216,6 +217,8 @@ class ValidLogLevel(registry.String):
self.error() self.error()
if level < self.minimumLevel: if level < self.minimumLevel:
self.error() self.error()
if self.handler is not None:
self.handler.setLevel(level)
self.setValue(level) self.setValue(level)
def __str__(self): def __str__(self):
@ -229,16 +232,12 @@ class ValidLogLevel(registry.String):
class LogLevel(ValidLogLevel): class LogLevel(ValidLogLevel):
"""Invalid log level. Value must be either DEBUG, INFO, WARNING, """Invalid log level. Value must be either DEBUG, INFO, WARNING,
ERROR, or CRITICAL.""" ERROR, or CRITICAL."""
def setValue(self, v): handler = _handler
ValidLogLevel.setValue(self, v)
_handler.setLevel(self.value)
class StdoutLogLevel(ValidLogLevel): class StdoutLogLevel(ValidLogLevel):
"""Invalid log level. Value must be either DEBUG, INFO, WARNING, """Invalid log level. Value must be either DEBUG, INFO, WARNING,
ERROR, or CRITICAL.""" ERROR, or CRITICAL."""
def setValue(self, v): handler = _stdoutHandler
ValidLogLevel.setValue(self, v)
_stdoutHandler.setLevel(self.value)
conf.registerGroup(conf.supybot, 'log') conf.registerGroup(conf.supybot, 'log')
conf.registerGlobalValue(conf.supybot.log, 'format', conf.registerGlobalValue(conf.supybot.log, 'format',