diff options
author | Alastair Tse <liquidx@gentoo.org> | 2004-06-28 14:08:18 +0000 |
---|---|---|
committer | Alastair Tse <liquidx@gentoo.org> | 2004-06-28 14:08:18 +0000 |
commit | b12ca75ec7a74dfa61268d720c43f2430dc786dd (patch) | |
tree | 70d5d63dd7bcf11894c8df0bafde4949d5ea7aff /net-irc | |
parent | * version bump (diff) | |
download | historical-b12ca75ec7a74dfa61268d720c43f2430dc786dd.tar.gz historical-b12ca75ec7a74dfa61268d720c43f2430dc786dd.tar.bz2 historical-b12ca75ec7a74dfa61268d720c43f2430dc786dd.zip |
sanitize patch so it doesn't get mangled by cvs (#55319)
Diffstat (limited to 'net-irc')
-rw-r--r-- | net-irc/supybot/ChangeLog | 6 | ||||
-rw-r--r-- | net-irc/supybot/Manifest | 4 | ||||
-rw-r--r-- | net-irc/supybot/files/supybot-0.77.2-cvsadditions-2004-06-10.patch | 1559 |
3 files changed, 702 insertions, 867 deletions
diff --git a/net-irc/supybot/ChangeLog b/net-irc/supybot/ChangeLog index 71fe0ce39ca5..69a2ea8246cb 100644 --- a/net-irc/supybot/ChangeLog +++ b/net-irc/supybot/ChangeLog @@ -1,6 +1,10 @@ # ChangeLog for net-irc/supybot # Copyright 2000-2004 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/net-irc/supybot/ChangeLog,v 1.5 2004/06/26 19:49:29 liquidx Exp $ +# $Header: /var/cvsroot/gentoo-x86/net-irc/supybot/ChangeLog,v 1.6 2004/06/28 14:08:18 liquidx Exp $ + + 28 Jun 2004; Alastair Tse <liquidx@gentoo.org> + files/supybot-0.77.2-cvsadditions-2004-06-10.patch: + sanitize patch so it doesn't get mangled by cvs (#55319) *supybot-0.77.2 (26 Jun 2004) diff --git a/net-irc/supybot/Manifest b/net-irc/supybot/Manifest index 14b7c3985cc6..312ac9a0bd4e 100644 --- a/net-irc/supybot/Manifest +++ b/net-irc/supybot/Manifest @@ -1,8 +1,8 @@ MD5 62a009a65f9081be3cba6d7f2c53b968 supybot-0.77.0.ebuild 908 MD5 5939cf77066f2537d93269b4270dd9f9 supybot-0.77.2.ebuild 1054 -MD5 61e4aad8239fa01d6bc4e6ecbee22354 ChangeLog 868 +MD5 09f12ec4cf5d4928a3fc2793a78a4cb2 ChangeLog 1031 MD5 eccd3e44b1e8fc954692d4faf329cf38 metadata.xml 218 MD5 e723df2ced2db8d65e4b8ed5026d2b2b files/supybot-0.77.0-setup.py.patch 629 MD5 67a13f83c4ad67ef8e6e25c06b67cf3e files/digest-supybot-0.77.0 67 MD5 220403a00e33177decd6e35d94c5d870 files/digest-supybot-0.77.2 67 -MD5 eb06bc679f69c20b9db2c84182777306 files/supybot-0.77.2-cvsadditions-2004-06-10.patch 33511 +MD5 89c91abb42a9debede75f29fc5445b5a files/supybot-0.77.2-cvsadditions-2004-06-10.patch 28392 diff --git a/net-irc/supybot/files/supybot-0.77.2-cvsadditions-2004-06-10.patch b/net-irc/supybot/files/supybot-0.77.2-cvsadditions-2004-06-10.patch index 2ee09a838340..ca7f106ac44a 100644 --- a/net-irc/supybot/files/supybot-0.77.2-cvsadditions-2004-06-10.patch +++ b/net-irc/supybot/files/supybot-0.77.2-cvsadditions-2004-06-10.patch @@ -1,23 +1,12 @@ -Index: others/amazon.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/others/amazon.py,v -retrieving revision 1.5 -retrieving revision 1.6 -diff -u -r1.5 -r1.6 ---- others/amazon.py 4 Dec 2003 01:56:50 -0000 1.5 -+++ others/amazon.py 17 May 2004 14:37:44 -0000 1.6 -@@ -55,8 +55,8 @@ -
- __author__ = "Mark Pilgrim (f8dy@diveintomark.org)"
- __version__ = "0.61"
--__cvsversion__ = "$Revision: 1.1 $"[11:-2]
--__date__ = "$Date: 2004/06/26 19:49:29 $"[7:-2]
-+__cvsversion__ = "$Revision: 1.1 $"[11:-2]
-+__date__ = "$Date: 2004/06/26 19:49:29 $"[7:-2]
- __copyright__ = "Copyright (c) 2002 Mark Pilgrim"
- __license__ = "Python"
- # Powersearch and return object type fix by Joseph Reagle <geek@goatee.net>
-@@ -174,7 +174,7 @@ +Index: others/amazon.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/others/amazon.py,v
+retrieving revision 1.5
+retrieving revision 1.6
+diff -u -r1.5 -r1.6
+--- others/amazon.py 4 Dec 2003 01:56:50 -0000 1.5
++++ others/amazon.py 17 May 2004 14:37:44 -0000 1.6
+@@ -174,7 +174,7 @@
return rc
def buildURL(search_type, keyword, product_line, type, page, license_key):
@@ -26,847 +15,689 @@ diff -u -r1.5 -r1.6 url += "&dev-t=%s" % license_key.strip()
url += "&type=%s" % type
if page:
-Index: others/babelfish.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/others/babelfish.py,v -retrieving revision 1.3 -retrieving revision 1.5 -diff -u -r1.3 -r1.5 ---- others/babelfish.py 21 Aug 2003 12:25:35 -0000 1.3 -+++ others/babelfish.py 9 Jun 2004 23:43:37 -0000 1.5 -@@ -53,7 +53,7 @@ - BabelizerIOError - Thrown for various networking and IO errors. - --Version: $Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $ -+Version: $Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $ - Author: Jonathan Feinberg <jdf@pobox.com> - """ - import re, string, urllib -@@ -66,6 +66,7 @@ - """ - __where = [ re.compile(r'lang=..>([^<]*)</div'), - re.compile(r'name=\"q\" value=\"([^\"]*)\">'), -+ re.compile(r'div style=padding:10px;>([^<]+)</div'), - ] - - __languages = { 'english' : 'en', -@@ -142,6 +143,7 @@ - for i in range(limit): - phrase = translate(phrase, next, flip[next]) - if seen.has_key(phrase): -+ next = flip[next] - break - seen[phrase] = 1 - if callback: -Index: plugins/Bugzilla.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Bugzilla.py,v -retrieving revision 1.38 -retrieving revision 1.39 -diff -u -r1.38 -r1.39 ---- plugins/Bugzilla.py 6 Feb 2004 04:36:21 -0000 1.38 -+++ plugins/Bugzilla.py 1 May 2004 19:53:28 -0000 1.39 -@@ -34,15 +34,13 @@ - Bugzilla bug retriever - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" - - import os - import re - import csv - import getopt --import string - import urllib --import urllib2 - import xml.dom.minidom as minidom - - from itertools import imap, ifilter -@@ -55,6 +53,7 @@ - import plugins - import ircutils - import privmsgs -+import webutils - import callbacks - import structures - -@@ -230,18 +229,26 @@ - """Given a URL and query list for a CSV bug list, it'll return - all the bugs in a dict - """ -- u = urllib2.urlopen(url + '/buglist.cgi', string.join(query, '&')) -+ bugs = {} -+ try: -+ url = '%s/buglist.cgi?%s' % (url, '&'.join(query)) -+ u = webutils.getUrlFd(url) -+ except webutils.WebError, e: -+ return bugs - # actually read in the file - csvreader = csv.reader(u) - # read header - fields = csvreader.next() - # read the rest of the list -- bugs = {} - for bug in csvreader: -+ if isinstance(bug, basestring): -+ bugid = bug -+ else: -+ bugid = bug[0] - try: -- bugid = int(bug[0]) -+ bugid = int(bugid) - except ValueError: -- bugid = bug[0] -+ pass - bugs[bugid] = {} - i = 1 - for f in fields[1:]: -@@ -278,6 +285,9 @@ - bugs = self.urlquery2bugslist(url, query) - bugids = bugs.keys() - bugids.sort() -+ if not bugs: -+ irc.error('I could not find any bugs.') -+ return - s = '%s match %r (%s): %s.' % \ - (utils.nItems('bug', len(bugs)), searchstr, - ' AND '.join(keywords), utils.commaAndify(map(str, bugids))) -@@ -373,11 +383,9 @@ - - def _getbugxml(self, url, desc): - try: -- fh = urllib2.urlopen(url) -- except urllib2.HTTPError, e: -+ bugxml = webutils.getUrl(url) -+ except webutils.WebError, e: - raise IOError, 'Connection to %s bugzilla failed' % desc -- bugxml = fh.read() -- fh.close() - if not bugxml: - raise IOError, 'Error getting bug content from %s' % desc - return bugxml -Index: plugins/Debian.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Debian.py,v -retrieving revision 1.53 -retrieving revision 1.56 -diff -u -r1.53 -r1.56 ---- plugins/Debian.py 1 Apr 2004 17:09:20 -0000 1.53 -+++ plugins/Debian.py 6 Jun 2004 21:18:18 -0000 1.56 -@@ -33,7 +33,8 @@ - This is a module to contain Debian-specific commands. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__author__ = "James Vega (jamessan) <jamessan@users.sf.net>" - - import plugins - -@@ -130,7 +131,7 @@ - glob = rest.pop() - regexp = fnmatch.translate(glob.lstrip('/')) - regexp = regexp.rstrip('$') -- regexp += ".* " -+ regexp = ".*%s.* " % regexp - try: - re_obj = re.compile(regexp, re.I) - except re.error, e: -@@ -138,12 +139,12 @@ - return - if self.registryValue('pythonZgrep'): - fd = gzip.open(self.contents) -- r = imap(lambda tup: tup[0], -+ r = imap(lambda tup: tup[0], - ifilter(lambda tup: tup[0], - imap(lambda line:(re_obj.search(line), line),fd))) - else: - try: -- (r, w) = popen2.popen4(['zgrep', '-e', regexp, self.contents]) -+ (r, w) = popen2.popen4(['zgrep', '-ie', regexp, self.contents]) - w.close() - except TypeError: - # We're on Windows. -@@ -160,7 +161,9 @@ - 'please narrow your search.') - return - try: -- (filename, pkg_list) = line[:-1].split() -+ if hasattr(line, 'group'): # we're actually using -+ line = line.group(0) # pythonZgrep :( -+ (filename, pkg_list) = line.split() - if filename == 'FILE': - # This is the last line before the actual files. - continue -@@ -261,7 +264,7 @@ - try: - fd = webutils.getUrlFd('http://incoming.debian.org/') - except webutils.WebError, e: -- irc.error(e) -+ irc.error(str(e)) - return - for line in fd: - m = self._incomingRe.search(line) -@@ -300,7 +303,7 @@ - fd = webutils.getUrlFd( - 'http://packages.debian.org/unstable/newpkg_%s' % section) - except webutils.WebError, e: -- irc.error(e) -+ irc.error(str(e)) - packages = [] - #self.log.warning(section) - #self.log.warning(glob) -@@ -357,7 +360,7 @@ - irc.reply(resp) - else: - irc.reply('I was unable to properly parse the BTS page.') -- -+ - Class = Debian - - # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: -Index: plugins/Dunno.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Dunno.py,v -retrieving revision 1.19 -retrieving revision 1.22 -diff -u -r1.19 -r1.22 ---- plugins/Dunno.py 5 Feb 2004 06:00:45 -0000 1.19 -+++ plugins/Dunno.py 6 May 2004 16:33:43 -0000 1.22 -@@ -34,7 +34,8 @@ - random "I dunno"-like responses. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__author__ = "Daniel DiPaolo (Strike) <ddipaolo@users.sf.net>" - - import os - import time -@@ -95,17 +96,19 @@ - """ - # Must be registered to use this - try: -- id = ircdb.users.getUserId(msg.prefix) -+ user_id = ircdb.users.getUserId(msg.prefix) - except KeyError: - irc.errorNotRegistered() - return -- text = privmsgs.getArgs(args, required=1) -+ text = privmsgs.getArgs(args) - cursor = self.db.cursor() -- cursor.execute("""INSERT INTO dunnos -- VALUES(NULL, %s, %s, %s)""", -- id, int(time.time()), text) -+ at = int(time.time()) -+ cursor.execute("""INSERT INTO dunnos VALUES(NULL, %s, %s, %s)""", -+ user_id, at, text) - self.db.commit() -- irc.replySuccess() -+ cursor.execute("""SELECT id FROM dunnos WHERE added_at=%s""", at) -+ id = cursor.fetchone()[0] -+ irc.replySuccess('Dunno #%s added.' % id) - - def remove(self, irc, msg, args): - """<id> -@@ -120,19 +123,17 @@ - return - dunno_id = privmsgs.getArgs(args, required=1) - cursor = self.db.cursor() -- cursor.execute("""SELECT added_by, dunno -- FROM dunnos -- WHERE id = %s""" % dunno_id) -+ cursor.execute("""SELECT added_by, dunno FROM dunnos -+ WHERE id=%s""", dunno_id) - if cursor.rowcount == 0: -- irc.error('No dunno with id: %s' % dunno_id) -+ irc.error('No dunno with id #%s.' % dunno_id) - return - (added_by, dunno) = cursor.fetchone() - if not (ircdb.checkCapability(user_id, 'admin') or \ - added_by == user_id): -- irc.error('Only admins and the dunno creator may delete a ' -- 'dunno.') -+ irc.error('Only admins and the dunno creator may delete a dunno.') - return -- cursor.execute("""DELETE FROM dunnos WHERE id = %s""" % dunno_id) -+ cursor.execute("""DELETE FROM dunnos WHERE id=%s""", dunno_id) - self.db.commit() - irc.replySuccess() - -@@ -145,13 +146,12 @@ - text = privmsgs.getArgs(args, required=1) - glob = "%" + text + "%" - cursor = self.db.cursor() -- cursor.execute("""SELECT id FROM dunnos -- WHERE dunno LIKE %s""", glob) -+ cursor.execute("""SELECT id FROM dunnos WHERE dunno LIKE %s""", glob) - if cursor.rowcount == 0: - irc.error('No dunnos with %r found.' % text) - return - ids = [str(t[0]) for t in cursor.fetchall()] -- s = 'Dunno search for %r (%s found): %s' % \ -+ s = 'Dunno search for %r (%s found): %s.' % \ - (text, len(ids), utils.commaAndify(ids)) - irc.reply(s) - -@@ -164,15 +164,15 @@ - try: - id = int(id) - except ValueError: -- irc.error('%r is not a valid dunno id' % id) -+ irc.error('%r is not a valid dunno id.' % id) - return - cursor = self.db.cursor() -- cursor.execute("""SELECT dunno FROM dunnos WHERE id = %s""", id) -+ cursor.execute("""SELECT dunno FROM dunnos WHERE id=%s""", id) - if cursor.rowcount == 0: -- irc.error('No dunno found with id #%s' % id) -+ irc.error('No dunno found with id #%s.' % id) - return - dunno = cursor.fetchone()[0] -- irc.reply("Dunno #%s: %r" % (id, dunno)) -+ irc.reply("Dunno #%s: %r." % (id, dunno)) - - def change(self, irc, msg, args): - """<id> <regexp> -@@ -184,23 +184,23 @@ - try: - user_id = ircdb.users.getUserId(msg.prefix) - except KeyError: -- irc.error(msg, conf.replyNotRegistered) -+ irc.errorNotRegistered() - return - # Check id arg - try: - id = int(id) - except ValueError: -- irc.error(msg, '%r is not a valid dunno id' % id) -+ irc.error('%r is not a valid dunno id.' % id) - return - cursor = self.db.cursor() - cursor.execute("""SELECT dunno FROM dunnos WHERE id=%s""", id) - if cursor.rowcount == 0: -- irc.error(msg, 'There is no dunno #%s' % id) -+ irc.error('There is no dunno #%s.' % id) - return - try: - replacer = utils.perlReToReplacer(regexp) - except: -- irc.error(msg, '%r is not a valid regexp' % regexp) -+ irc.error('%r is not a valid regular expression.' % regexp) - return - dunno = cursor.fetchone()[0] - new_dunno = replacer(dunno) -Index: plugins/Enforcer.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Enforcer.py,v -retrieving revision 1.47 -retrieving revision 1.49 -diff -u -r1.47 -r1.49 ---- plugins/Enforcer.py 5 Apr 2004 15:57:22 -0000 1.47 -+++ plugins/Enforcer.py 28 Apr 2004 06:30:55 -0000 1.49 -@@ -36,7 +36,8 @@ - empty channel in order to get ops. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__author__ = 'Jeremy Fincher (jemfinch) <jemfinch@users.sf.net>' - - import plugins - -@@ -162,8 +163,14 @@ - return False # Default. - - def _revenge(self, irc, channel, hostmask): -- irc.queueMsg(ircmsgs.ban(channel, ircutils.banmask(hostmask))) -- irc.queueMsg(ircmsgs.kick(channel,ircutils.nickFromHostmask(hostmask))) -+ nick = ircutils.nickFromHostmask(hostmask) -+ if irc.nick != nick: -+ irc.queueMsg(ircmsgs.ban(channel, ircutils.banmask(hostmask))) -+ irc.queueMsg(ircmsgs.kick(channel, nick)) -+ else: -+ # This can happen if takeRevengeOnOps is True. -+ self.log.info('Tried to take revenge on myself. ' -+ 'Are you sure you want takeRevengeOnOps to be True?') - - def doKick(self, irc, msg): - channel = msg.args[0] -Index: plugins/FunDB.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/FunDB.py,v -retrieving revision 1.91 -retrieving revision 1.92 -diff -u -r1.91 -r1.92 ---- plugins/FunDB.py 13 Apr 2004 04:08:15 -0000 1.91 -+++ plugins/FunDB.py 7 Jun 2004 05:17:50 -0000 1.92 -@@ -33,7 +33,7 @@ - Provides fun commands that require a database to operate. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" - - import plugins - -@@ -344,9 +344,10 @@ - (id, insult) = cursor.fetchone() - nick = re.sub(r'\bme\b', msg.nick, nick) - nick = re.sub(r'\bmy\b', '%s\'s' % msg.nick, nick) -- insult = insult.replace('$who', nick) -+ insult = '%s: %s' % (nick, insult.replace('$who', nick)) - showid = self.registryValue('showIds', channel) -- irc.reply(self._formatResponse(insult, id, showid), to=nick) -+ irc.reply(self._formatResponse(insult, id, showid), -+ prefixName=False) - - def excuse(self, irc, msg, args): - """[<channel>] [<id>] -Index: plugins/Http.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Http.py,v -retrieving revision 1.138 -retrieving revision 1.143 -diff -u -r1.138 -r1.143 ---- plugins/Http.py 26 Mar 2004 00:56:31 -0000 1.138 -+++ plugins/Http.py 1 May 2004 19:25:19 -0000 1.143 -@@ -250,7 +252,7 @@ - s = ', or '.join(defs) - irc.reply('%s could be %s' % (acronym, s)) - -- _netcraftre = re.compile(r'whatos text -->(.*?)<a href="/up/acc', re.S) -+ _netcraftre = re.compile(r'td align="left">\s+<a[^>]+>(.*?)<a href', re.S) - def netcraft(self, irc, msg, args): - """<hostname|ip> - -@@ -263,8 +265,9 @@ - m = self._netcraftre.search(html) - if m: - html = m.group(1) -- s = utils.htmlToText(html, tagReplace='').strip('\xa0 ') -- irc.reply(s[9:]) # Snip off "the site" -+ s = utils.htmlToText(html, tagReplace='').strip() -+ s = s.rstrip('-').strip() -+ irc.reply(s) # Snip off "the site" - elif 'We could not get any results' in html: - irc.reply('No results found for %s.' % hostname) - else: -Index: plugins/Python.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Python.py,v -retrieving revision 1.33 -retrieving revision 1.34 -diff -u -r1.33 -r1.34 ---- plugins/Python.py 6 Feb 2004 04:36:21 -0000 1.33 -+++ plugins/Python.py 2 Jun 2004 05:16:54 -0000 1.34 -@@ -34,7 +34,7 @@ - written in) somehow. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" - - import plugins - -@@ -48,9 +48,11 @@ - - # Stupid printing on import... - from cStringIO import StringIO --sys.stdout = StringIO() --import this --sys.stdout = sys.__stdout__ -+try: -+ sys.stdout = StringIO() -+ import this -+finally: -+ sys.stdout = sys.__stdout__ - - import conf - import utils -Index: plugins/Relay.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Relay.py,v -retrieving revision 1.163 -retrieving revision 1.166 -diff -u -r1.163 -r1.166 ---- plugins/Relay.py 18 Apr 2004 00:35:54 -0000 1.163 -+++ plugins/Relay.py 10 May 2004 22:17:45 -0000 1.166 -@@ -33,7 +33,8 @@ - Handles relaying between networks. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__author__ = 'Jeremy Fincher (jemfinch) <jemfinch@users.sf.net>' - - import plugins - -@@ -217,7 +218,7 @@ - Starts relaying between the channel <channel> on all networks. If on a - network the bot isn't in <channel>, he'll join. This commands is - required even if the bot is in the channel on both networks; he won't -- relay between those channels unless he's told to oin both -+ relay between those channels unless he's told to join both - channels. - """ - if not self.started: -@@ -596,6 +597,8 @@ - if msg.nick == irc.nick: - return - (channel, newTopic) = msg.args -+ if channel not in self.registryValue('channels'): -+ return - network = self.abbreviations[irc] - if self.registryValue('topicSync', channel): - m = ircmsgs.topic(channel, newTopic) -Index: plugins/Scheduler.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Scheduler.py,v -retrieving revision 1.17 -retrieving revision 1.19 -diff -u -r1.17 -r1.19 ---- plugins/Scheduler.py 29 Mar 2004 16:52:42 -0000 1.17 -+++ plugins/Scheduler.py 27 May 2004 16:47:05 -0000 1.19 -@@ -34,7 +34,8 @@ - or repeatedly run at a particular interval. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__author__ = 'Jeremy Fincher (jemfinch) <jemfinch@users.sf.net>' - - import plugins - -@@ -62,7 +63,7 @@ - raise callbacks.Error, callbacks.ambiguousReply(ambiguous) - def f(): - if remove: -- del self.events[f.eventId] -+ del self.events[str(f.eventId)] - self.Proxy(irc.irc, msg, tokens) - return f - -@@ -70,7 +71,7 @@ - """<seconds> <command> - - Schedules the command string <command> to run <seconds> seconds in the -- future. For example, 'schedule add [seconds 30m] "echo [cpu]"' will -+ future. For example, 'scheduler add [seconds 30m] "echo [cpu]"' will - schedule the command "cpu" to be sent to the channel the schedule add - command was given in (with no prefixed nick, a consequence of using - echo). -Index: plugins/Services.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Services.py,v -retrieving revision 1.43 -retrieving revision 1.45 -diff -u -r1.43 -r1.45 ---- plugins/Services.py 16 Apr 2004 07:59:47 -0000 1.43 -+++ plugins/Services.py 4 Jun 2004 06:14:29 -0000 1.45 -@@ -33,7 +33,7 @@ - Services: Handles management of nicks with NickServ, and ops with ChanServ. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" - - import plugins - -@@ -56,8 +56,8 @@ - chanserv = something('What is your ChanServ named?', default='ChanServ') - nickserv = something('What is your NickServ named?', default='NickServ') - conf.supybot.plugins.Services.nick.setValue(nick) -- conf.supybot.plugins.Services.password.setValue(password) - conf.supybot.plugins.Services.NickServ.setValue(nickserv) -+ conf.supybot.plugins.Services.NickServ.password.setValue(password) - conf.supybot.plugins.Services.ChanServ.setValue(chanserv) - - class ValidNickOrEmptyString(registry.String): -@@ -66,7 +66,7 @@ - raise registry.InvalidRegistryValue, \ - 'Value must be a valid nick or the empty string.' - registry.String.setValue(self, v) -- -+ - conf.registerPlugin('Services') - # Not really ChannelValues: but we can have values for each network. We - # should probably document that this is possible. -Index: plugins/Sourceforge.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Sourceforge.py,v -retrieving revision 1.71 -retrieving revision 1.74 -diff -u -r1.71 -r1.74 ---- plugins/Sourceforge.py 16 Apr 2004 16:31:17 -0000 1.71 -+++ plugins/Sourceforge.py 1 May 2004 21:38:49 -0000 1.74 -@@ -33,6 +33,9 @@ - Accesses Sourceforge.net for various things - """ - -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__author__ = "James Vega (jamessan) <jamessan@users.sf.net>" -+ - import re - import sets - import getopt -@@ -43,7 +46,6 @@ - - import conf - import utils --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" - - import plugins - import ircutils -@@ -116,7 +118,7 @@ - _statusOpt = {'any':100, 'open':1, 'closed':2, 'deleted':3, 'pending':4} - - _projectURL = 'http://sourceforge.net/projects/' -- _trackerURL = 'https://sourceforge.net/support/tracker.php?aid=' -+ _trackerURL = 'http://sourceforge.net/support/tracker.php?aid=' - def __init__(self): - callbacks.PrivmsgCommandAndRegexp.__init__(self) - self.__class__.sf = self.__class__.sourceforge -@@ -150,6 +152,8 @@ - def _getTrackerList(self, url): - try: - text = webutils.getUrl(url) -+ if "No matches found." in text: -+ return 'No trackers were found.' - head = '#%s: %s' - resp = [head % entry for entry in self._formatResp(text)] - if resp: -Index: plugins/Words.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/Words.py,v -retrieving revision 1.22 -retrieving revision 1.23 -diff -u -r1.22 -r1.23 ---- plugins/Words.py 27 Mar 2004 13:30:46 -0000 1.22 -+++ plugins/Words.py 29 Apr 2004 11:52:20 -0000 1.23 -@@ -33,7 +33,7 @@ - This handles interesting things to do with a dictionary (words) database. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" - - import supybot - import plugins -@@ -104,10 +104,13 @@ - - def getWord(self, dbHandler): - db = dbHandler.getDb() -- cur = db.cursor() -- cur.execute("""SELECT word FROM words ORDER BY random() LIMIT 1""") -- word = cur.fetchone()[0] -- return word.lower() -+ cursor = db.cursor() -+ cursor.execute("""SELECT word FROM words ORDER BY random() LIMIT 1""") -+ if cursor.rowcount != 0: -+ word = cursor.fetchone()[0] -+ return word.lower() -+ else: -+ raise callbacks.Error, 'My words database is currently empty.' - - def letterPositions(self, letter, word): - """ -Index: scripts/supybot-adduser -=================================================================== -RCS file: /cvsroot/supybot/supybot/scripts/supybot-adduser,v -retrieving revision 1.8 -retrieving revision 1.9 -diff -u -r1.8 -r1.9 ---- scripts/supybot-adduser 7 Feb 2004 23:14:58 -0000 1.8 -+++ scripts/supybot-adduser 29 Apr 2004 11:05:53 -0000 1.9 -@@ -44,7 +44,7 @@ - conf.supybot.log.stdout.setValue(False) - #conf.supybot.log.level.set('DEBUG') - -- parser = optparse.OptionParser(usage='Usage: %prog [options] <configFile>', -+ parser = optparse.OptionParser(usage='Usage: %prog [options] <users.conf>', - version='supybot %s' % conf.version) - parser.add_option('-u', '--username', action='store', default='', - dest='name', -@@ -64,7 +64,7 @@ - 'this option may be given multiple times.') - (options, args) = parser.parse_args() - if len(args) is not 1: -- parser.error('specify the configuration file you\'d like to use.') -+ parser.error('Specify the users.conf file you\'d like to use.') - - filename = os.path.abspath(args[0]) - conf.supybot.directories.log.setValue('/') -Index: src/Admin.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/src/Admin.py,v -retrieving revision 1.34 -retrieving revision 1.38 -diff -u -r1.34 -r1.38 ---- src/Admin.py 16 Apr 2004 07:39:55 -0000 1.34 -+++ src/Admin.py 11 May 2004 17:41:54 -0000 1.38 -@@ -34,7 +34,8 @@ - caller to have the 'admin' capability. This plugin is loaded by default. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__author__ = 'Jeremy Fincher (jemfinch) <jemfinch@users.sf.net>' - - import fix - -@@ -53,6 +54,7 @@ - import ircmsgs - import ircutils - import privmsgs -+import schedule - import callbacks - - -@@ -78,6 +80,20 @@ - irc.queueMsg(ircmsgs.joins(chans, keys)) - do422 = do377 = do376 - -+ def do437(self, irc, msg): -+ """Nick/channel temporarily unavailable.""" -+ target = msg.args[0] -+ if ircutils.isChannel(target): # We don't care about nicks. -+ t = time.time() + 30 -+ # Let's schedule a rejoin. -+ def rejoin(): -+ irc.queueMsg(ircmsgs.join(target)) -+ # We don't need to schedule something because we'll get another -+ # 437 when we try to join later. -+ schedule.addEvent(rejoin, t) -+ self.log.info('Scheduling a rejoin to %s at %s; ' -+ 'Channel temporarily unavailable.', target, t) -+ - def do471(self, irc, msg): - try: - channel = msg.args[1] -@@ -196,7 +212,10 @@ - - def doNick(self, irc, msg): - if msg.nick == irc.nick or msg.args[0] == irc.nick: -- del self.pendingNickChanges[irc] -+ try: -+ del self.pendingNickChanges[irc] -+ except KeyError: -+ self.log.debug('Got NICK without Admin.nick being called.') - - def nick(self, irc, msg, args): - """<nick> -Index: src/socketDrivers.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/src/socketDrivers.py,v -retrieving revision 1.39 -retrieving revision 1.41 -diff -u -r1.39 -r1.41 ---- src/socketDrivers.py 12 Apr 2004 21:44:03 -0000 1.39 -+++ src/socketDrivers.py 19 Apr 2004 04:36:26 -0000 1.41 -@@ -35,7 +35,7 @@ - - from __future__ import division - --__revision__ ="$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ ="$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" - - import fix - -@@ -141,7 +141,8 @@ - self.irc.reset() - self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - # We allow more time for the connect here, since it might take longer. -- self.conn.settimeout(conf.supybot.drivers.poll()*10) -+ # At least 10 seconds. -+ self.conn.settimeout(max(10, conf.supybot.drivers.poll()*10)) - if self.reconnectWaitsIndex < len(self.reconnectWaits)-1: - self.reconnectWaitsIndex += 1 - try: -Index: plugins/URL.py -=================================================================== -RCS file: /cvsroot/supybot/supybot/plugins/URL.py,v -retrieving revision 1.35 -retrieving revision 1.39 -diff -u -r1.35 -r1.39 ---- plugins/URL.py 27 Feb 2004 17:20:57 -0000 1.35 -+++ plugins/URL.py 7 Jun 2004 19:45:49 -0000 1.39 -@@ -35,7 +35,7 @@ - URLs in the database. - """ - --__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" -+__revision__ = "$Id: supybot-0.77.2-cvsadditions-2004-06-10.patch,v 1.1 2004/06/26 19:49:29 liquidx Exp $" - - import plugins - -@@ -171,8 +171,11 @@ - if not ircutils.isChannel(msg.args[0]): - return - channel = msg.args[0] -+ r = self.registryValue('nonSnarfingRegexp', channel) - if self.registryValue('tinyurlSnarfer', channel): - url = match.group(0) -+ if r and r.search(url): -+ return - minlen = self.registryValue('tinyurlSnarfer.minimumLength',channel) - if len(url) >= minlen: - db = self.getDb(channel) -@@ -195,10 +198,15 @@ - if callbacks.addressed(irc.nick, msg): - return - channel = msg.args[0] -+ r = self.registryValue('nonSnarfingRegexp', channel) -+ #self.log.warning('Title: %r' % r) - if self.registryValue('titleSnarfer', channel): - url = match.group(0) -+ if r and r.search(url): -+ return - try: -- text = webutils.getUrl(url, size=conf.supybot.httpPeekSize()) -+ size = conf.supybot.httpPeekSize() -+ text = webutils.getUrl(url, size=size) - except webutils.WebError, e: - self.log.info('Couldn\'t snarf title of %s, %s.', url, e) - return -@@ -221,7 +229,7 @@ - WHERE tinyurl=%s""", id, tinyurl) - db.commit() - -- _tinyRe = re.compile(r'(http://tinyurl\.com/\w+)</blockquote>') -+ _tinyRe = re.compile(r'<blockquote><b>(http://tinyurl\.com/\w+)</b>') - def _getTinyUrl(self, url, channel, cmd=False): - db = self.getDb(channel) - cursor = db.cursor() -@@ -279,14 +287,14 @@ - Returns a TinyURL.com version of <url> - """ - url = privmsgs.getArgs(args) -- if len(url) < 24: -- irc.error( -- 'Stop being a lazy-biotch and type the URL yourself.') -+ if len(url) < 20: -+ irc.error('Stop being a lazy-biotch and type the URL yourself.') - return - channel = msg.args[0] - snarf = self.registryValue('tinyurlSnarfer', channel) - minlen = self.registryValue('tinyurlSnarfer.minimumLength', channel) -- if snarf and len(url) >= minlen: -+ r = self.registryValue('nonSnarfingRegexp', channel) -+ if snarf and len(url) >= minlen and not r.search(url): - return - (tinyurl, updateDb) = self._getTinyUrl(url, channel, cmd=True) - if tinyurl: -@@ -309,8 +317,9 @@ - cursor = db.cursor() - cursor.execute("""SELECT COUNT(*) FROM urls""") - (count,) = cursor.fetchone() -+ count = int(count) - irc.reply('I have %s %s in my database.' % -- (count, int(count) == 1 and 'URL' or 'URLs')) -+ (count, count == 1 and 'URL' or 'URLs')) - - def last(self, irc, msg, args): - """[<channel>] [--{from,with,at,proto,near}=<value>] --{nolimit,fancy} +Index: others/babelfish.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/others/babelfish.py,v
+retrieving revision 1.3
+retrieving revision 1.5
+diff -u -r1.3 -r1.5
+--- others/babelfish.py 21 Aug 2003 12:25:35 -0000 1.3
++++ others/babelfish.py 9 Jun 2004 23:43:37 -0000 1.5
+@@ -66,6 +66,7 @@
+ """
+ __where = [ re.compile(r'lang=..>([^<]*)</div'),
+ re.compile(r'name=\"q\" value=\"([^\"]*)\">'),
++ re.compile(r'div style=padding:10px;>([^<]+)</div'),
+ ]
+
+ __languages = { 'english' : 'en',
+@@ -142,6 +143,7 @@
+ for i in range(limit):
+ phrase = translate(phrase, next, flip[next])
+ if seen.has_key(phrase):
++ next = flip[next]
+ break
+ seen[phrase] = 1
+ if callback:
+Index: plugins/Bugzilla.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Bugzilla.py,v
+retrieving revision 1.38
+retrieving revision 1.39
+diff -u -r1.38 -r1.39
+--- plugins/Bugzilla.py 6 Feb 2004 04:36:21 -0000 1.38
++++ plugins/Bugzilla.py 1 May 2004 19:53:28 -0000 1.39
+@@ -55,6 +53,7 @@
+ import plugins
+ import ircutils
+ import privmsgs
++import webutils
+ import callbacks
+ import structures
+
+@@ -230,18 +229,26 @@
+ """Given a URL and query list for a CSV bug list, it'll return
+ all the bugs in a dict
+ """
+- u = urllib2.urlopen(url + '/buglist.cgi', string.join(query, '&'))
++ bugs = {}
++ try:
++ url = '%s/buglist.cgi?%s' % (url, '&'.join(query))
++ u = webutils.getUrlFd(url)
++ except webutils.WebError, e:
++ return bugs
+ # actually read in the file
+ csvreader = csv.reader(u)
+ # read header
+ fields = csvreader.next()
+ # read the rest of the list
+- bugs = {}
+ for bug in csvreader:
++ if isinstance(bug, basestring):
++ bugid = bug
++ else:
++ bugid = bug[0]
+ try:
+- bugid = int(bug[0])
++ bugid = int(bugid)
+ except ValueError:
+- bugid = bug[0]
++ pass
+ bugs[bugid] = {}
+ i = 1
+ for f in fields[1:]:
+@@ -278,6 +285,9 @@
+ bugs = self.urlquery2bugslist(url, query)
+ bugids = bugs.keys()
+ bugids.sort()
++ if not bugs:
++ irc.error('I could not find any bugs.')
++ return
+ s = '%s match %r (%s): %s.' % \
+ (utils.nItems('bug', len(bugs)), searchstr,
+ ' AND '.join(keywords), utils.commaAndify(map(str, bugids)))
+@@ -373,11 +383,9 @@
+
+ def _getbugxml(self, url, desc):
+ try:
+- fh = urllib2.urlopen(url)
+- except urllib2.HTTPError, e:
++ bugxml = webutils.getUrl(url)
++ except webutils.WebError, e:
+ raise IOError, 'Connection to %s bugzilla failed' % desc
+- bugxml = fh.read()
+- fh.close()
+ if not bugxml:
+ raise IOError, 'Error getting bug content from %s' % desc
+ return bugxml
+Index: plugins/Debian.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Debian.py,v
+retrieving revision 1.53
+retrieving revision 1.56
+diff -u -r1.53 -r1.56
+--- plugins/Debian.py 1 Apr 2004 17:09:20 -0000 1.53
++++ plugins/Debian.py 6 Jun 2004 21:18:18 -0000 1.56
+@@ -130,7 +131,7 @@
+ glob = rest.pop()
+ regexp = fnmatch.translate(glob.lstrip('/'))
+ regexp = regexp.rstrip('$')
+- regexp += ".* "
++ regexp = ".*%s.* " % regexp
+ try:
+ re_obj = re.compile(regexp, re.I)
+ except re.error, e:
+@@ -138,12 +139,12 @@
+ return
+ if self.registryValue('pythonZgrep'):
+ fd = gzip.open(self.contents)
+- r = imap(lambda tup: tup[0],
++ r = imap(lambda tup: tup[0],
+ ifilter(lambda tup: tup[0],
+ imap(lambda line:(re_obj.search(line), line),fd)))
+ else:
+ try:
+- (r, w) = popen2.popen4(['zgrep', '-e', regexp, self.contents])
++ (r, w) = popen2.popen4(['zgrep', '-ie', regexp, self.contents])
+ w.close()
+ except TypeError:
+ # We're on Windows.
+@@ -160,7 +161,9 @@
+ 'please narrow your search.')
+ return
+ try:
+- (filename, pkg_list) = line[:-1].split()
++ if hasattr(line, 'group'): # we're actually using
++ line = line.group(0) # pythonZgrep :(
++ (filename, pkg_list) = line.split()
+ if filename == 'FILE':
+ # This is the last line before the actual files.
+ continue
+@@ -261,7 +264,7 @@
+ try:
+ fd = webutils.getUrlFd('http://incoming.debian.org/')
+ except webutils.WebError, e:
+- irc.error(e)
++ irc.error(str(e))
+ return
+ for line in fd:
+ m = self._incomingRe.search(line)
+@@ -300,7 +303,7 @@
+ fd = webutils.getUrlFd(
+ 'http://packages.debian.org/unstable/newpkg_%s' % section)
+ except webutils.WebError, e:
+- irc.error(e)
++ irc.error(str(e))
+ packages = []
+ #self.log.warning(section)
+ #self.log.warning(glob)
+@@ -357,7 +360,7 @@
+ irc.reply(resp)
+ else:
+ irc.reply('I was unable to properly parse the BTS page.')
+-
++
+ Class = Debian
+
+ # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
+Index: plugins/Dunno.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Dunno.py,v
+retrieving revision 1.19
+retrieving revision 1.22
+diff -u -r1.19 -r1.22
+--- plugins/Dunno.py 5 Feb 2004 06:00:45 -0000 1.19
++++ plugins/Dunno.py 6 May 2004 16:33:43 -0000 1.22
+@@ -95,17 +96,19 @@
+ """
+ # Must be registered to use this
+ try:
+- id = ircdb.users.getUserId(msg.prefix)
++ user_id = ircdb.users.getUserId(msg.prefix)
+ except KeyError:
+ irc.errorNotRegistered()
+ return
+- text = privmsgs.getArgs(args, required=1)
++ text = privmsgs.getArgs(args)
+ cursor = self.db.cursor()
+- cursor.execute("""INSERT INTO dunnos
+- VALUES(NULL, %s, %s, %s)""",
+- id, int(time.time()), text)
++ at = int(time.time())
++ cursor.execute("""INSERT INTO dunnos VALUES(NULL, %s, %s, %s)""",
++ user_id, at, text)
+ self.db.commit()
+- irc.replySuccess()
++ cursor.execute("""SELECT id FROM dunnos WHERE added_at=%s""", at)
++ id = cursor.fetchone()[0]
++ irc.replySuccess('Dunno #%s added.' % id)
+
+ def remove(self, irc, msg, args):
+ """<id>
+@@ -120,19 +123,17 @@
+ return
+ dunno_id = privmsgs.getArgs(args, required=1)
+ cursor = self.db.cursor()
+- cursor.execute("""SELECT added_by, dunno
+- FROM dunnos
+- WHERE id = %s""" % dunno_id)
++ cursor.execute("""SELECT added_by, dunno FROM dunnos
++ WHERE id=%s""", dunno_id)
+ if cursor.rowcount == 0:
+- irc.error('No dunno with id: %s' % dunno_id)
++ irc.error('No dunno with id #%s.' % dunno_id)
+ return
+ (added_by, dunno) = cursor.fetchone()
+ if not (ircdb.checkCapability(user_id, 'admin') or \
+ added_by == user_id):
+- irc.error('Only admins and the dunno creator may delete a '
+- 'dunno.')
++ irc.error('Only admins and the dunno creator may delete a dunno.')
+ return
+- cursor.execute("""DELETE FROM dunnos WHERE id = %s""" % dunno_id)
++ cursor.execute("""DELETE FROM dunnos WHERE id=%s""", dunno_id)
+ self.db.commit()
+ irc.replySuccess()
+
+@@ -145,13 +146,12 @@
+ text = privmsgs.getArgs(args, required=1)
+ glob = "%" + text + "%"
+ cursor = self.db.cursor()
+- cursor.execute("""SELECT id FROM dunnos
+- WHERE dunno LIKE %s""", glob)
++ cursor.execute("""SELECT id FROM dunnos WHERE dunno LIKE %s""", glob)
+ if cursor.rowcount == 0:
+ irc.error('No dunnos with %r found.' % text)
+ return
+ ids = [str(t[0]) for t in cursor.fetchall()]
+- s = 'Dunno search for %r (%s found): %s' % \
++ s = 'Dunno search for %r (%s found): %s.' % \
+ (text, len(ids), utils.commaAndify(ids))
+ irc.reply(s)
+
+@@ -164,15 +164,15 @@
+ try:
+ id = int(id)
+ except ValueError:
+- irc.error('%r is not a valid dunno id' % id)
++ irc.error('%r is not a valid dunno id.' % id)
+ return
+ cursor = self.db.cursor()
+- cursor.execute("""SELECT dunno FROM dunnos WHERE id = %s""", id)
++ cursor.execute("""SELECT dunno FROM dunnos WHERE id=%s""", id)
+ if cursor.rowcount == 0:
+- irc.error('No dunno found with id #%s' % id)
++ irc.error('No dunno found with id #%s.' % id)
+ return
+ dunno = cursor.fetchone()[0]
+- irc.reply("Dunno #%s: %r" % (id, dunno))
++ irc.reply("Dunno #%s: %r." % (id, dunno))
+
+ def change(self, irc, msg, args):
+ """<id> <regexp>
+@@ -184,23 +184,23 @@
+ try:
+ user_id = ircdb.users.getUserId(msg.prefix)
+ except KeyError:
+- irc.error(msg, conf.replyNotRegistered)
++ irc.errorNotRegistered()
+ return
+ # Check id arg
+ try:
+ id = int(id)
+ except ValueError:
+- irc.error(msg, '%r is not a valid dunno id' % id)
++ irc.error('%r is not a valid dunno id.' % id)
+ return
+ cursor = self.db.cursor()
+ cursor.execute("""SELECT dunno FROM dunnos WHERE id=%s""", id)
+ if cursor.rowcount == 0:
+- irc.error(msg, 'There is no dunno #%s' % id)
++ irc.error('There is no dunno #%s.' % id)
+ return
+ try:
+ replacer = utils.perlReToReplacer(regexp)
+ except:
+- irc.error(msg, '%r is not a valid regexp' % regexp)
++ irc.error('%r is not a valid regular expression.' % regexp)
+ return
+ dunno = cursor.fetchone()[0]
+ new_dunno = replacer(dunno)
+Index: plugins/Enforcer.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Enforcer.py,v
+retrieving revision 1.47
+retrieving revision 1.49
+diff -u -r1.47 -r1.49
+--- plugins/Enforcer.py 5 Apr 2004 15:57:22 -0000 1.47
++++ plugins/Enforcer.py 28 Apr 2004 06:30:55 -0000 1.49
+@@ -162,8 +163,14 @@
+ return False # Default.
+
+ def _revenge(self, irc, channel, hostmask):
+- irc.queueMsg(ircmsgs.ban(channel, ircutils.banmask(hostmask)))
+- irc.queueMsg(ircmsgs.kick(channel,ircutils.nickFromHostmask(hostmask)))
++ nick = ircutils.nickFromHostmask(hostmask)
++ if irc.nick != nick:
++ irc.queueMsg(ircmsgs.ban(channel, ircutils.banmask(hostmask)))
++ irc.queueMsg(ircmsgs.kick(channel, nick))
++ else:
++ # This can happen if takeRevengeOnOps is True.
++ self.log.info('Tried to take revenge on myself. '
++ 'Are you sure you want takeRevengeOnOps to be True?')
+
+ def doKick(self, irc, msg):
+ channel = msg.args[0]
+Index: plugins/FunDB.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/FunDB.py,v
+retrieving revision 1.91
+retrieving revision 1.92
+diff -u -r1.91 -r1.92
+--- plugins/FunDB.py 13 Apr 2004 04:08:15 -0000 1.91
++++ plugins/FunDB.py 7 Jun 2004 05:17:50 -0000 1.92
+@@ -344,9 +344,10 @@
+ (id, insult) = cursor.fetchone()
+ nick = re.sub(r'\bme\b', msg.nick, nick)
+ nick = re.sub(r'\bmy\b', '%s\'s' % msg.nick, nick)
+- insult = insult.replace('$who', nick)
++ insult = '%s: %s' % (nick, insult.replace('$who', nick))
+ showid = self.registryValue('showIds', channel)
+- irc.reply(self._formatResponse(insult, id, showid), to=nick)
++ irc.reply(self._formatResponse(insult, id, showid),
++ prefixName=False)
+
+ def excuse(self, irc, msg, args):
+ """[<channel>] [<id>]
+Index: plugins/Http.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Http.py,v
+retrieving revision 1.138
+retrieving revision 1.143
+diff -u -r1.138 -r1.143
+--- plugins/Http.py 26 Mar 2004 00:56:31 -0000 1.138
++++ plugins/Http.py 1 May 2004 19:25:19 -0000 1.143
+@@ -250,7 +252,7 @@
+ s = ', or '.join(defs)
+ irc.reply('%s could be %s' % (acronym, s))
+
+- _netcraftre = re.compile(r'whatos text -->(.*?)<a href="/up/acc', re.S)
++ _netcraftre = re.compile(r'td align="left">\s+<a[^>]+>(.*?)<a href', re.S)
+ def netcraft(self, irc, msg, args):
+ """<hostname|ip>
+
+@@ -263,8 +265,9 @@
+ m = self._netcraftre.search(html)
+ if m:
+ html = m.group(1)
+- s = utils.htmlToText(html, tagReplace='').strip('\xa0 ')
+- irc.reply(s[9:]) # Snip off "the site"
++ s = utils.htmlToText(html, tagReplace='').strip()
++ s = s.rstrip('-').strip()
++ irc.reply(s) # Snip off "the site"
+ elif 'We could not get any results' in html:
+ irc.reply('No results found for %s.' % hostname)
+ else:
+Index: plugins/Python.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Python.py,v
+retrieving revision 1.33
+retrieving revision 1.34
+diff -u -r1.33 -r1.34
+--- plugins/Python.py 6 Feb 2004 04:36:21 -0000 1.33
++++ plugins/Python.py 2 Jun 2004 05:16:54 -0000 1.34
+@@ -48,9 +48,11 @@
+
+ # Stupid printing on import...
+ from cStringIO import StringIO
+-sys.stdout = StringIO()
+-import this
+-sys.stdout = sys.__stdout__
++try:
++ sys.stdout = StringIO()
++ import this
++finally:
++ sys.stdout = sys.__stdout__
+
+ import conf
+ import utils
+Index: plugins/Relay.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Relay.py,v
+retrieving revision 1.163
+retrieving revision 1.166
+diff -u -r1.163 -r1.166
+--- plugins/Relay.py 18 Apr 2004 00:35:54 -0000 1.163
++++ plugins/Relay.py 10 May 2004 22:17:45 -0000 1.166
+@@ -217,7 +218,7 @@
+ Starts relaying between the channel <channel> on all networks. If on a
+ network the bot isn't in <channel>, he'll join. This commands is
+ required even if the bot is in the channel on both networks; he won't
+- relay between those channels unless he's told to oin both
++ relay between those channels unless he's told to join both
+ channels.
+ """
+ if not self.started:
+@@ -596,6 +597,8 @@
+ if msg.nick == irc.nick:
+ return
+ (channel, newTopic) = msg.args
++ if channel not in self.registryValue('channels'):
++ return
+ network = self.abbreviations[irc]
+ if self.registryValue('topicSync', channel):
+ m = ircmsgs.topic(channel, newTopic)
+Index: plugins/Scheduler.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Scheduler.py,v
+retrieving revision 1.17
+retrieving revision 1.19
+diff -u -r1.17 -r1.19
+--- plugins/Scheduler.py 29 Mar 2004 16:52:42 -0000 1.17
++++ plugins/Scheduler.py 27 May 2004 16:47:05 -0000 1.19
+@@ -62,7 +63,7 @@
+ raise callbacks.Error, callbacks.ambiguousReply(ambiguous)
+ def f():
+ if remove:
+- del self.events[f.eventId]
++ del self.events[str(f.eventId)]
+ self.Proxy(irc.irc, msg, tokens)
+ return f
+
+@@ -70,7 +71,7 @@
+ """<seconds> <command>
+
+ Schedules the command string <command> to run <seconds> seconds in the
+- future. For example, 'schedule add [seconds 30m] "echo [cpu]"' will
++ future. For example, 'scheduler add [seconds 30m] "echo [cpu]"' will
+ schedule the command "cpu" to be sent to the channel the schedule add
+ command was given in (with no prefixed nick, a consequence of using
+ echo).
+Index: plugins/Services.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Services.py,v
+retrieving revision 1.43
+retrieving revision 1.45
+diff -u -r1.43 -r1.45
+--- plugins/Services.py 16 Apr 2004 07:59:47 -0000 1.43
++++ plugins/Services.py 4 Jun 2004 06:14:29 -0000 1.45
+@@ -56,8 +56,8 @@
+ chanserv = something('What is your ChanServ named?', default='ChanServ')
+ nickserv = something('What is your NickServ named?', default='NickServ')
+ conf.supybot.plugins.Services.nick.setValue(nick)
+- conf.supybot.plugins.Services.password.setValue(password)
+ conf.supybot.plugins.Services.NickServ.setValue(nickserv)
++ conf.supybot.plugins.Services.NickServ.password.setValue(password)
+ conf.supybot.plugins.Services.ChanServ.setValue(chanserv)
+
+ class ValidNickOrEmptyString(registry.String):
+@@ -66,7 +66,7 @@
+ raise registry.InvalidRegistryValue, \
+ 'Value must be a valid nick or the empty string.'
+ registry.String.setValue(self, v)
+-
++
+ conf.registerPlugin('Services')
+ # Not really ChannelValues: but we can have values for each network. We
+ # should probably document that this is possible.
+Index: plugins/Sourceforge.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Sourceforge.py,v
+retrieving revision 1.71
+retrieving revision 1.74
+diff -u -r1.71 -r1.74
+--- plugins/Sourceforge.py 16 Apr 2004 16:31:17 -0000 1.71
++++ plugins/Sourceforge.py 1 May 2004 21:38:49 -0000 1.74
+@@ -116,7 +118,7 @@
+ _statusOpt = {'any':100, 'open':1, 'closed':2, 'deleted':3, 'pending':4}
+
+ _projectURL = 'http://sourceforge.net/projects/'
+- _trackerURL = 'https://sourceforge.net/support/tracker.php?aid='
++ _trackerURL = 'http://sourceforge.net/support/tracker.php?aid='
+ def __init__(self):
+ callbacks.PrivmsgCommandAndRegexp.__init__(self)
+ self.__class__.sf = self.__class__.sourceforge
+@@ -150,6 +152,8 @@
+ def _getTrackerList(self, url):
+ try:
+ text = webutils.getUrl(url)
++ if "No matches found." in text:
++ return 'No trackers were found.'
+ head = '#%s: %s'
+ resp = [head % entry for entry in self._formatResp(text)]
+ if resp:
+Index: plugins/Words.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/Words.py,v
+retrieving revision 1.22
+retrieving revision 1.23
+diff -u -r1.22 -r1.23
+--- plugins/Words.py 27 Mar 2004 13:30:46 -0000 1.22
++++ plugins/Words.py 29 Apr 2004 11:52:20 -0000 1.23
+@@ -104,10 +104,13 @@
+
+ def getWord(self, dbHandler):
+ db = dbHandler.getDb()
+- cur = db.cursor()
+- cur.execute("""SELECT word FROM words ORDER BY random() LIMIT 1""")
+- word = cur.fetchone()[0]
+- return word.lower()
++ cursor = db.cursor()
++ cursor.execute("""SELECT word FROM words ORDER BY random() LIMIT 1""")
++ if cursor.rowcount != 0:
++ word = cursor.fetchone()[0]
++ return word.lower()
++ else:
++ raise callbacks.Error, 'My words database is currently empty.'
+
+ def letterPositions(self, letter, word):
+ """
+Index: scripts/supybot-adduser
+===================================================================
+RCS file: /cvsroot/supybot/supybot/scripts/supybot-adduser,v
+retrieving revision 1.8
+retrieving revision 1.9
+diff -u -r1.8 -r1.9
+--- scripts/supybot-adduser 7 Feb 2004 23:14:58 -0000 1.8
++++ scripts/supybot-adduser 29 Apr 2004 11:05:53 -0000 1.9
+@@ -44,7 +44,7 @@
+ conf.supybot.log.stdout.setValue(False)
+ #conf.supybot.log.level.set('DEBUG')
+
+- parser = optparse.OptionParser(usage='Usage: %prog [options] <configFile>',
++ parser = optparse.OptionParser(usage='Usage: %prog [options] <users.conf>',
+ version='supybot %s' % conf.version)
+ parser.add_option('-u', '--username', action='store', default='',
+ dest='name',
+@@ -64,7 +64,7 @@
+ 'this option may be given multiple times.')
+ (options, args) = parser.parse_args()
+ if len(args) is not 1:
+- parser.error('specify the configuration file you\'d like to use.')
++ parser.error('Specify the users.conf file you\'d like to use.')
+
+ filename = os.path.abspath(args[0])
+ conf.supybot.directories.log.setValue('/')
+Index: src/Admin.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/src/Admin.py,v
+retrieving revision 1.34
+retrieving revision 1.38
+diff -u -r1.34 -r1.38
+--- src/Admin.py 16 Apr 2004 07:39:55 -0000 1.34
++++ src/Admin.py 11 May 2004 17:41:54 -0000 1.38
+@@ -53,6 +54,7 @@
+ import ircmsgs
+ import ircutils
+ import privmsgs
++import schedule
+ import callbacks
+
+
+@@ -78,6 +80,20 @@
+ irc.queueMsg(ircmsgs.joins(chans, keys))
+ do422 = do377 = do376
+
++ def do437(self, irc, msg):
++ """Nick/channel temporarily unavailable."""
++ target = msg.args[0]
++ if ircutils.isChannel(target): # We don't care about nicks.
++ t = time.time() + 30
++ # Let's schedule a rejoin.
++ def rejoin():
++ irc.queueMsg(ircmsgs.join(target))
++ # We don't need to schedule something because we'll get another
++ # 437 when we try to join later.
++ schedule.addEvent(rejoin, t)
++ self.log.info('Scheduling a rejoin to %s at %s; '
++ 'Channel temporarily unavailable.', target, t)
++
+ def do471(self, irc, msg):
+ try:
+ channel = msg.args[1]
+@@ -196,7 +212,10 @@
+
+ def doNick(self, irc, msg):
+ if msg.nick == irc.nick or msg.args[0] == irc.nick:
+- del self.pendingNickChanges[irc]
++ try:
++ del self.pendingNickChanges[irc]
++ except KeyError:
++ self.log.debug('Got NICK without Admin.nick being called.')
+
+ def nick(self, irc, msg, args):
+ """<nick>
+Index: src/socketDrivers.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/src/socketDrivers.py,v
+retrieving revision 1.39
+retrieving revision 1.41
+diff -u -r1.39 -r1.41
+--- src/socketDrivers.py 12 Apr 2004 21:44:03 -0000 1.39
++++ src/socketDrivers.py 19 Apr 2004 04:36:26 -0000 1.41
+@@ -141,7 +141,8 @@
+ self.irc.reset()
+ self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ # We allow more time for the connect here, since it might take longer.
+- self.conn.settimeout(conf.supybot.drivers.poll()*10)
++ # At least 10 seconds.
++ self.conn.settimeout(max(10, conf.supybot.drivers.poll()*10))
+ if self.reconnectWaitsIndex < len(self.reconnectWaits)-1:
+ self.reconnectWaitsIndex += 1
+ try:
+Index: plugins/URL.py
+===================================================================
+RCS file: /cvsroot/supybot/supybot/plugins/URL.py,v
+retrieving revision 1.35
+retrieving revision 1.39
+diff -u -r1.35 -r1.39
+--- plugins/URL.py 27 Feb 2004 17:20:57 -0000 1.35
++++ plugins/URL.py 7 Jun 2004 19:45:49 -0000 1.39
+@@ -171,8 +171,11 @@
+ if not ircutils.isChannel(msg.args[0]):
+ return
+ channel = msg.args[0]
++ r = self.registryValue('nonSnarfingRegexp', channel)
+ if self.registryValue('tinyurlSnarfer', channel):
+ url = match.group(0)
++ if r and r.search(url):
++ return
+ minlen = self.registryValue('tinyurlSnarfer.minimumLength',channel)
+ if len(url) >= minlen:
+ db = self.getDb(channel)
+@@ -195,10 +198,15 @@
+ if callbacks.addressed(irc.nick, msg):
+ return
+ channel = msg.args[0]
++ r = self.registryValue('nonSnarfingRegexp', channel)
++ #self.log.warning('Title: %r' % r)
+ if self.registryValue('titleSnarfer', channel):
+ url = match.group(0)
++ if r and r.search(url):
++ return
+ try:
+- text = webutils.getUrl(url, size=conf.supybot.httpPeekSize())
++ size = conf.supybot.httpPeekSize()
++ text = webutils.getUrl(url, size=size)
+ except webutils.WebError, e:
+ self.log.info('Couldn\'t snarf title of %s, %s.', url, e)
+ return
+@@ -221,7 +229,7 @@
+ WHERE tinyurl=%s""", id, tinyurl)
+ db.commit()
+
+- _tinyRe = re.compile(r'(http://tinyurl\.com/\w+)</blockquote>')
++ _tinyRe = re.compile(r'<blockquote><b>(http://tinyurl\.com/\w+)</b>')
+ def _getTinyUrl(self, url, channel, cmd=False):
+ db = self.getDb(channel)
+ cursor = db.cursor()
+@@ -279,14 +287,14 @@
+ Returns a TinyURL.com version of <url>
+ """
+ url = privmsgs.getArgs(args)
+- if len(url) < 24:
+- irc.error(
+- 'Stop being a lazy-biotch and type the URL yourself.')
++ if len(url) < 20:
++ irc.error('Stop being a lazy-biotch and type the URL yourself.')
+ return
+ channel = msg.args[0]
+ snarf = self.registryValue('tinyurlSnarfer', channel)
+ minlen = self.registryValue('tinyurlSnarfer.minimumLength', channel)
+- if snarf and len(url) >= minlen:
++ r = self.registryValue('nonSnarfingRegexp', channel)
++ if snarf and len(url) >= minlen and not r.search(url):
+ return
+ (tinyurl, updateDb) = self._getTinyUrl(url, channel, cmd=True)
+ if tinyurl:
+@@ -309,8 +317,9 @@
+ cursor = db.cursor()
+ cursor.execute("""SELECT COUNT(*) FROM urls""")
+ (count,) = cursor.fetchone()
++ count = int(count)
+ irc.reply('I have %s %s in my database.' %
+- (count, int(count) == 1 and 'URL' or 'URLs'))
++ (count, count == 1 and 'URL' or 'URLs'))
+
+ def last(self, irc, msg, args):
+ """[<channel>] [--{from,with,at,proto,near}=<value>] --{nolimit,fancy}
|