pybot-commits Mailing List for pybot (Page 5)
Brought to you by:
niemeyer
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(6) |
Dec
(7) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
|
Feb
|
Mar
(1) |
Apr
(7) |
May
(1) |
Jun
(14) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(56) |
Jun
(4) |
Jul
|
Aug
(85) |
Sep
(2) |
Oct
|
Nov
|
Dec
|
From: Gustavo N. <nie...@us...> - 2003-05-29 05:06:45
|
Update of /cvsroot/pybot/pybot/pybot/util/SOAPpy In directory sc8-pr-cvs1:/tmp/cvs-serv2897/SOAPpy Log Message: Directory /cvsroot/pybot/pybot/pybot/util/SOAPpy added to the repository |
From: Gustavo N. <nie...@us...> - 2003-05-23 21:29:32
|
Update of /cvsroot/pybot/pybot/data/infopacks In directory sc8-pr-cvs1:/tmp/cvs-serv8069/data/infopacks Added Files: versions.info Log Message: Created new infopack to show which versions of any given package were released in past Conectiva Linux distributions. To do that, a script was created to convert hdlist information to the infopack format. --- NEW FILE: versions.info --- # Infopack for pybot providing information about versions of packages # released in Conectiva Linux. # H:This infopack provides information about which package versions were released in past versions of Conectiva Linux. You can check a given package with "[show] versions [of] <packagename>". T:(?:show\s+)?versions\s+(?:of\s+)?(\S+) D:t:No information about that package. D:t:I have never seen that package. D:t:Sorry, I don't know anything about that package. M:This package has been released in the following distributions: %s M:The following distributions contain that package: %s M:You'll find that package in the following distributions: %s M:It was included in the following distributions: %s K:0verkill V:tm:CL6-CD2: 0.13-1cl; CL9-CD3: 0.16-23753cl K:3270-common V:tm:CL7-CD2: 1:3.2.16-2cl; CL8-CD2: 1:3.2.18p7-1cl; CL9-CD1: 1:3.2.18p15-25718cl K:3270-doc V:tm:CL7-CD2: 1:3.2.16-2cl; CL8-CD2: 1:3.2.18p7-1cl; CL9-CD1: 1:3.2.18p15-25718cl K:aalib [...12641 lines suppressed...] K:zmailer V:tm:CL9-CD1: 2.99.55-14155cl K:zope V:tm:CL5-CD2: 2.1.2-2cl; CL5.1-CD1: 2.1.7-2cl; CL6-CD1: 2.1.7-7cl K:zope-components V:tm:CL5-CD2: 2.1.2-2cl; CL5.1-CD1: 2.1.7-2cl; CL6-CD1: 2.1.7-7cl K:zope-core V:tm:CL5-CD2: 2.1.2-2cl; CL5.1-CD1: 2.1.7-2cl; CL6-CD1: 2.1.7-7cl K:zope-pcgi V:tm:CL5-CD2: 2.1.2-2cl; CL5.1-CD1: 2.1.7-2cl; CL6-CD1: 2.1.7-7cl K:zope-services V:tm:CL5-CD2: 2.1.2-2cl; CL5.1-CD1: 2.1.7-2cl; CL6-CD1: 2.1.7-7cl K:zope-zpublisher V:tm:CL5-CD2: 2.1.2-2cl; CL5.1-CD1: 2.1.7-2cl; CL6-CD1: 2.1.7-7cl K:zope-ztemplates V:tm:CL5-CD2: 2.1.2-2cl; CL5.1-CD1: 2.1.7-2cl; CL6-CD1: 2.1.7-7cl K:zsh V:tm:CL4: 3.0.5-12cl; CL5-CD1: 3.0.7-1cl; CL5.1-CD1: 3.0.7-1cl; CL6-CD1: 3.0.7-4cl; CL7-CD1: 3.0.8-1cl; CL8-CD2: 4.0.4-3cl; CL9-CD2: 4.0.6-14160cl K:zsh-doc V:tm:CL8-CD2: 4.0.4-3cl; CL9-CD2: 4.0.6-14160cl |
From: Gustavo N. <nie...@us...> - 2003-05-23 21:29:32
|
Update of /cvsroot/pybot/pybot/contrib In directory sc8-pr-cvs1:/tmp/cvs-serv8069/contrib Added Files: hdlist2info.py Log Message: Created new infopack to show which versions of any given package were released in past Conectiva Linux distributions. To do that, a script was created to convert hdlist information to the infopack format. --- NEW FILE: hdlist2info.py --- #!/usr/bin/python import sys, os import rpm def main(): if len(sys.argv) != 4: sys.exit("Usage: hdlist2ipack.py <label> <hdlist> <infopack>") label = sys.argv[1] hdlistname = sys.argv[2] ipackname = sys.argv[3] packages = {} if os.path.exists(ipackname): file = open(ipackname) name = None for line in file.readlines(): if line[0] == "K": name = line.rstrip().split(":")[1] elif name and line[0] == "V": value = line.rstrip().split(":", 2)[2] for pair in value.split(";"): distrostr, versionstr = pair.split(":", 1) distros = packages.setdefault(name, {}) versions = distros.setdefault(distrostr.strip(), {}) for version in versionstr.split(","): versions[version.strip()] = 1 file.close() for h in rpm.readHeaderListFromFile(hdlistname): if h["epoch"]: version = "%s:%s-%s" % (h["epoch"], h["version"], h["release"]) else: version = "%s-%s" % (h["version"], h["release"]) distros = packages.setdefault(h["name"].lower(), {}) versions = distros.setdefault(label, {}) versions[version] = 1 if os.path.exists(ipackname): file = open(ipackname) oldlines = file.readlines() file.close() else: oldlines = [] file = open(ipackname, "w") for line in oldlines: if line[0] not in ("K", "V"): file.write(line) packagenames = packages.keys() packagenames.sort() for packagename in packagenames: file.write("K:%s\n" % packagename) v = "" distros = packages[packagename] distronames = distros.keys() distronames.sort() for distroname in distronames: if v: v += "; " versions = distros[distroname].keys() versions.sort() v += "%s: %s" % (distroname, ", ".join(versions)) file.write("V:tm:%s\n" % v) file.close() if __name__ == "__main__": main() |
From: Gustavo N. <nie...@us...> - 2003-05-23 21:29:32
|
Update of /cvsroot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv8069 Modified Files: TODO Log Message: Created new infopack to show which versions of any given package were released in past Conectiva Linux distributions. To do that, a script was created to convert hdlist information to the infopack format. Index: TODO =================================================================== RCS file: /cvsroot/pybot/pybot/TODO,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** TODO 16 May 2003 17:28:03 -0000 1.7 --- TODO 23 May 2003 21:29:29 -0000 1.8 *************** *** 16,17 **** --- 16,26 ---- - Develop admin module for direct sql access. + + - Add timed messages in the messages.py module. + + - Perhaps a google module (including a random link fetcher)? + + - Perhaps a "karma" module, implementing word++ and word--? + + - Check ideas from http://olut.ton.tut.fi/~karhu/ and http://supybot.sf.net. + |
From: Gustavo N. <nie...@us...> - 2003-05-20 17:06:56
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv13759 Modified Files: log.py Log Message: Logs were being shown in the wrong order. Index: log.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/log.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** log.py 12 May 2003 22:18:07 -0000 1.12 --- log.py 20 May 2003 17:06:53 -0000 1.13 *************** *** 108,112 **** cursor = db.cursor() cursor.execute("select * from log where src != '' and dest != '' " ! "order by timestamp desc") row = cursor.fetchone() while row: --- 108,112 ---- cursor = db.cursor() cursor.execute("select * from log where src != '' and dest != '' " ! "order by timestamp") row = cursor.fetchone() while row: |
From: Gustavo N. <nie...@us...> - 2003-05-16 17:34:45
|
Update of /cvsroot/pybot/pybot/data/infopacks In directory sc8-pr-cvs1:/tmp/cvs-serv7925 Modified Files: vera.info Log Message: Forgot to add header entries in vera.info. Index: vera.info =================================================================== RCS file: /cvsroot/pybot/pybot/data/infopacks/vera.info,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** vera.info 16 May 2003 17:28:03 -0000 1.3 --- vera.info 16 May 2003 17:34:42 -0000 1.4 *************** *** 7,10 **** --- 7,17 ---- # ftp://ftp.gnu.org/gnu/vera # + H:This infopack provides the VERA database of acronyms. You can check for a given a acronym using "acronym <acronym>". + T:acronym\s+(\w+)\s*\?*$ + D:t:No acronym for that. + D:t:I don't know this acronym. + D:t:Sorry, I haven't found this acronym. + M:That's the acronym for %s. + M:This acronym is for %s. K:100vg V:tm:100 Voice Grade [technology] |
From: Gustavo N. <nie...@us...> - 2003-05-16 17:32:57
|
Update of /cvsroot/pybot/pybot/data/infopacks In directory sc8-pr-cvs1:/tmp/cvs-serv4173/data/infopacks Modified Files: vera.info Log Message: * contrib/vera2info.py: Updated to add multiple values in the same key, when the keys are the same. * data/infopacks/vera.info: Updated to vera 1.9. Index: vera.info =================================================================== RCS file: /cvsroot/pybot/pybot/data/infopacks/vera.info,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** vera.info 12 May 2003 20:42:19 -0000 1.2 --- vera.info 16 May 2003 17:28:03 -0000 1.3 *************** *** 1,17 **** # Infopack of acronyms for pybot. # ! # This file has been generated from VERA 1.7 (Virtual Entity of Relevant ! # Acronyms) and is also released under the General Public License (GPL). The ! # original VERA files may be found at the GNU ftp site: # # ftp://ftp.gnu.org/gnu/vera # - H:This infopack provides the VERA database of acronyms. You can check for a given a acronym using "acronym <acronym>". - T:acronym\s+(\w+)\s*\?*$ [...21327 lines suppressed...] V:tm:Zentrum fuer Multimediale Telekommunikation (BERKOM) K:zoc ! V:tm:Zap-O-Comm (OS/2, telecommunication) ! K:zos ! V:tm:Z/Operating System (IBM, Java), "z/OS" ! K:zpl ! V:tm:Zope Puplic License K:zpr ! V:tm:Zentrum fuer Paralleles Rechnen (org., Uni Koeln, Germany), Zero Power Resistance K:zre V:tm:Zero Rate Error *************** *** 16862,16865 **** --- 14229,14234 ---- K:zv V:tm:Zoomed Video (video) + K:zvm + V:tm:Z/Virtual Machine (IBM, VM), "z/VM" K:zwei V:tm:ZWEI Was EINE Initially (EINE, LISP) |
From: Gustavo N. <nie...@us...> - 2003-05-16 17:28:07
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv4173/pybot/modules Modified Files: infopack.py Log Message: * contrib/vera2info.py: Updated to add multiple values in the same key, when the keys are the same. * data/infopacks/vera.info: Updated to vera 1.9. Index: infopack.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/infopack.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** infopack.py 12 May 2003 20:42:21 -0000 1.5 --- infopack.py 16 May 2003 17:28:03 -0000 1.6 *************** *** 18,22 **** from pybot import config, hooks, mm, db ! from random import randrange import re import os --- 18,22 ---- from pybot import config, hooks, mm, db ! import random import re import os *************** *** 157,163 **** values = self.getinfo(key) if values: ! value = values[randrange(len(values))] elif self._defaults: ! value = self._defaults[randrange(len(self._defaults))] else: break --- 157,163 ---- values = self.getinfo(key) if values: ! value = random.choice(values) elif self._defaults: ! value = random.choice(self._defaults) else: break *************** *** 168,172 **** info.tonick = "t" in flags if "m" in flags: ! mask = self._masks[randrange(len(self._masks))] info.phrase = mask%value[1] else: --- 168,172 ---- info.tonick = "t" in flags if "m" in flags: ! mask = random.choice(self._masks) info.phrase = mask%value[1] else: |
From: Gustavo N. <nie...@us...> - 2003-05-16 17:28:06
|
Update of /cvsroot/pybot/pybot/contrib In directory sc8-pr-cvs1:/tmp/cvs-serv4173/contrib Modified Files: vera2info.py Log Message: * contrib/vera2info.py: Updated to add multiple values in the same key, when the keys are the same. * data/infopacks/vera.info: Updated to vera 1.9. Index: vera2info.py =================================================================== RCS file: /cvsroot/pybot/pybot/contrib/vera2info.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** vera2info.py 2 Nov 2001 17:19:01 -0000 1.1.1.1 --- vera2info.py 16 May 2003 17:28:03 -0000 1.2 *************** *** 3,18 **** def main(): ! for filename in sys.argv[1:]: ! file = open(filename) ! nextisvalue = 0 ! for line in file.xreadlines(): ! if line[:6] == "@item ": ! print "K:"+line[6:].rstrip() ! nextisvalue = 1 ! elif nextisvalue: ! print "V:tm:"+line.rstrip() ! nextisvalue = 0 ! file.close() if __name__ == "__main__": ! main() --- 3,37 ---- def main(): ! lastkey = None ! append = 0 ! nextisvalue = 0 ! for filename in sys.argv[1:]: ! file = open(filename) ! nextisvalue = 0 ! for line in file.xreadlines(): ! if line[:6] == "@item ": ! key = line[6:].rstrip().lower() ! if key != lastkey: ! if lastkey and not nextisvalue: ! sys.stdout.write("\n") ! lastkey = key ! sys.stdout.write("K:%s\n" % key) ! append = 0 ! else: ! append = 1 ! nextisvalue = 1 ! elif nextisvalue: ! value = line.rstrip() ! if not append: ! sys.stdout.write("V:tm:%s" % value) ! else: ! sys.stdout.write(", %s" % value) ! nextisvalue = 0 ! file.close() ! if lastkey and not nextisvalue: ! sys.stdout.write("\n") if __name__ == "__main__": ! main() ! ! # vim:ts=4:sw=4:et |
From: Gustavo N. <nie...@us...> - 2003-05-16 17:28:05
|
Update of /cvsroot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv4173 Modified Files: ChangeLog README TODO Log Message: * contrib/vera2info.py: Updated to add multiple values in the same key, when the keys are the same. * data/infopacks/vera.info: Updated to vera 1.9. Index: ChangeLog =================================================================== RCS file: /cvsroot/pybot/pybot/ChangeLog,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** ChangeLog 12 May 2003 20:42:18 -0000 1.14 --- ChangeLog 16 May 2003 17:28:03 -0000 1.15 *************** *** 1,2 **** --- 1,7 ---- + 2003-05-16 Gustavo Niemeyer <nie...@co...> + * contrib/vera2info.py: Updated to add multiple values in the + same key, when the keys are the same. + * data/infopacks/vera.info: Updated to vera 1.9. + 2003-05-12 Gustavo Niemeyer <nie...@co...> * *: Major work on pybot!! Index: README =================================================================== RCS file: /cvsroot/pybot/pybot/README,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** README 12 May 2003 21:56:33 -0000 1.2 --- README 16 May 2003 17:28:03 -0000 1.3 *************** *** 81,84 **** --- 81,88 ---- Answers ping requests, and pings servers from time to time. + - log + Allows searching in logs, and checking what was the last time + the bot has seen somebody. + - ignore Allows ignoring given users/channels/servers. Index: TODO =================================================================== RCS file: /cvsroot/pybot/pybot/TODO,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** TODO 12 May 2003 20:42:18 -0000 1.6 --- TODO 16 May 2003 17:28:03 -0000 1.7 *************** *** 12,13 **** --- 12,17 ---- - Setup pybot nick when connecting. + + - Limit log search to the same server. + + - Develop admin module for direct sql access. |
From: Gustavo N. <nie...@us...> - 2003-05-13 14:13:44
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv14257 Modified Files: forward.py Log Message: Minor fixes in forward module. Index: forward.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/forward.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** forward.py 12 May 2003 20:42:21 -0000 1.4 --- forward.py 13 May 2003 14:13:40 -0000 1.5 *************** *** 84,88 **** row.fromserver == server.servername) and \ (row.fromtarget is None or row.fromtarget == target) and \ ! (forme or "f" in row.flags): fwdserver = servers.get(row.toserver) if fwdserver: --- 84,88 ---- row.fromserver == server.servername) and \ (row.fromtarget is None or row.fromtarget == target) and \ ! (forme or "f" not in row.flags): fwdserver = servers.get(row.toserver) if fwdserver: *************** *** 190,193 **** --- 190,198 ---- "Right now", "Of course"], ["!", "."]) + else: + msg.answer("%:", ["You're not allowed to work with forwards", + "Unfortunately, you can't do that", + "You're not able to do that"], + [".", "!"]) return 0 *************** *** 232,235 **** --- 237,245 ---- str = str+" with server" msg.answer("%:", str, ".") + else: + msg.answer("%:", ["You're not allowed to work with forwards", + "Unfortunately, you can't do that", + "You're not able to do that"], + [".", "!"]) return 0 |
From: Gustavo N. <nie...@us...> - 2003-05-12 23:49:34
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv6906/pybot/modules Modified Files: log.py Log Message: Fixed return in "seen" command. Index: log.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/log.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** log.py 12 May 2003 20:42:21 -0000 1.10 --- log.py 12 May 2003 22:16:52 -0000 1.11 *************** *** 183,187 **** "last time I saw somebody", "that good", "allowed to do this"]), ! "No", "Nope"], [".", "!"]) m = self.re2.match(msg.line) if m: --- 183,189 ---- "last time I saw somebody", "that good", "allowed to do this"]), ! [".", "!"]) ! return 0 ! m = self.re2.match(msg.line) if m: |
From: Gustavo N. <nie...@us...> - 2003-05-12 23:30:25
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv7449/pybot/modules Modified Files: log.py Log Message: Oops.. fixed typo. Index: log.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/log.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** log.py 12 May 2003 22:16:52 -0000 1.11 --- log.py 12 May 2003 22:18:07 -0000 1.12 *************** *** 179,186 **** return 0 else: ! msg.answer("%:", [("You're not", ! ["allowed to know when was the " ! "last time I saw somebody", ! "that good", "allowed to do this"]), [".", "!"]) return 0 --- 179,186 ---- return 0 else: ! msg.answer("%:", "You're not", ! ["allowed to know when was the " ! "last time I saw somebody", ! "that good", "allowed to do this"], [".", "!"]) return 0 |
From: Gustavo N. <nie...@us...> - 2003-05-12 23:03:01
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv24568/modules Modified Files: xmlrpc.py Log Message: - Fixed xmlrpc SQL statement in hasperm() method. - Disabled message sending amortization for now. Index: xmlrpc.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/xmlrpc.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** xmlrpc.py 12 May 2003 20:42:21 -0000 1.3 --- xmlrpc.py 12 May 2003 23:02:58 -0000 1.4 *************** *** 71,79 **** self.server.socket.setblocking(0) - rm.register("sendmsg", self.rm_sendmsg) - xro = XmlRpcObject(rm.get_methods(), self.hasperm) self.server.register_instance(xro) hooks.register("Message", self.message) hooks.register("Loop", self.loop) --- 71,79 ---- self.server.socket.setblocking(0) xro = XmlRpcObject(rm.get_methods(), self.hasperm) self.server.register_instance(xro) + rm.register("sendmsg", self.rm_sendmsg) + hooks.register("Message", self.message) hooks.register("Loop", self.loop) *************** *** 224,228 **** cursor.execute("select * from xmlrpcperm " "natural left join xmlrpcuser where " ! "username=%s and password=%s and " "(servername isnull or servername=%s) and " "(target isnull or target=%s)", --- 224,228 ---- cursor.execute("select * from xmlrpcperm " "natural left join xmlrpcuser where " ! "xmlrpcuser.username=%s and password=%s and " "(servername isnull or servername=%s) and " "(target isnull or target=%s)", |
From: Gustavo N. <nie...@us...> - 2003-05-12 23:03:01
|
Update of /cvsroot/pybot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv24568 Modified Files: server.py Log Message: - Fixed xmlrpc SQL statement in hasperm() method. - Disabled message sending amortization for now. Index: server.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/server.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** server.py 12 May 2003 20:42:20 -0000 1.4 --- server.py 12 May 2003 23:02:58 -0000 1.5 *************** *** 161,168 **** lines_sent = 0 while lines_sent < 3 and self._outlines and (self._outlines[0][1] <= 20 or self._last_sent < time()): ! if self._last_sent+2 < time(): ! self._last_sent_timeout = 1 ! elif self._last_sent_timeout < 5 and self._outlines[0][1] > 20: ! self._last_sent_timeout = self._last_sent_timeout+1 self._last_sent = time()+self._last_sent_timeout; line = self._outlines[0][0]+"\r\n" --- 161,169 ---- lines_sent = 0 while lines_sent < 3 and self._outlines and (self._outlines[0][1] <= 20 or self._last_sent < time()): ! # Disabled for now. ! #if self._last_sent+1 < time(): ! # self._last_sent_timeout = 1 ! #elif self._last_sent_timeout < 2 and self._outlines[0][1] > 20: ! # self._last_sent_timeout = self._last_sent_timeout+1 self._last_sent = time()+self._last_sent_timeout; line = self._outlines[0][0]+"\r\n" |
From: Gustavo N. <nie...@us...> - 2003-05-12 21:56:36
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv28477/pybot/modules Modified Files: permission.py Log Message: - Fixed return code of setperm() Index: permission.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/permission.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** permission.py 12 May 2003 20:42:21 -0000 1.9 --- permission.py 12 May 2003 21:56:33 -0000 1.10 *************** *** 255,258 **** --- 255,259 ---- cursor.execute("insert into permission values (%s,%s,%s,%s,%s)", perm, servername, target, userstr, nick) + return bool(cursor.rowcount) def mm_unsetperm(self, servername, target, userstr, nick, perm, check=0): |
From: Gustavo N. <nie...@us...> - 2003-05-12 21:56:36
|
Update of /cvsroot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv28477 Modified Files: README pybot.conf Log Message: - Fixed return code of setperm() Index: README =================================================================== RCS file: /cvsroot/pybot/pybot/README,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** README 12 May 2003 21:28:33 -0000 1.1 --- README 12 May 2003 21:56:33 -0000 1.2 *************** *** 63,66 **** --- 63,70 ---- users have given privilege. + - userdata (*) + Provides some general user data storage, and exports some + functions providing this information for other modules. + - help (*) Provides online help system. *************** *** 123,130 **** - randnum Simple random number generator. - - - userdata - Provides some general user data storage, and exports some - functions providing this information for other modules. - xmlrpc --- 127,130 ---- Index: pybot.conf =================================================================== RCS file: /cvsroot/pybot/pybot/pybot.conf,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pybot.conf 9 May 2003 20:18:36 -0000 1.6 --- pybot.conf 12 May 2003 21:56:33 -0000 1.7 *************** *** 18,22 **** ; system (send "help permission" to pybot for more information), or just ; append an entry here and restart pybot. ! admins = nie...@ir... [userdata] --- 18,22 ---- ; system (send "help permission" to pybot for more information), or just ; append an entry here and restart pybot. ! admins = niemeyer@conectiva [userdata] |
From: Gustavo N. <nie...@us...> - 2003-05-12 21:31:12
|
Update of /cvsroot/pybot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv12954/pybot Modified Files: runner.py Log Message: Added userdata to default loaded modules. Index: runner.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/runner.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** runner.py 12 May 2003 20:42:20 -0000 1.3 --- runner.py 12 May 2003 21:31:09 -0000 1.4 *************** *** 86,91 **** # Load modules which are part of the basic infrastructure ! pybot.modls.loadlist(["help", "options", "timer", "modulecontrol", ! "permission", "pong", "servercontrol"]) ret = pybot.main.loop() sys.exit(ret) --- 86,100 ---- # Load modules which are part of the basic infrastructure ! defaultlist = [ ! "help", ! "options", ! "timer", ! "modulecontrol", ! "permission", ! "pong", ! "servercontrol", ! "userdata", ! ] ! pybot.modls.loadlist(defaultlist) ret = pybot.main.loop() sys.exit(ret) |
From: Gustavo N. <nie...@us...> - 2003-05-12 21:28:36
|
Update of /cvsroot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv11687 Added Files: README Log Message: Created basic README file. --- NEW FILE: README --- What is pybot? -------------- Pybot is a full featured IRC bot written in Python. It was originally developed to integrate many sources of information into IRC channels, and has since then evolved into a full featured bot. Requirements ------------ Pybot requires the sqlite (http://sqlite.org) SQL database library, and its python module (http://pysqlite.sf.net). End user features ----------------- - easy administration through local console; - may join multiple servers and multiple channels at once (implemented without threads); - full online control (just talk to him); - load, reload and unload modules at runtime; - flexible user registry, allowing automatic identification and manual identification under different nicks; - very flexible permission system; - full online help; - auto recover from network errors; - flood protection; - auto timming of messages to avoid being kicked by the server. - lots of additional functionalities through available modules; - even basic functionality is implemented using modules; - random answers, to humanify the bot a little bit; - persistence implemented with transparent pickling and sqlite database; Developer features ------------------ - nice API for inter-module communication; - object oriented; - hook system for multidispatch with priority setting; - message priority; - example modules; - user registry allows pluggable meta-data; Standard modules ---------------- (*) modules which are part of the basic infrastructure, loaded without user intervention - modulecontrol (*) Takes care of loading, reloading, and unloading modules dynamically and when pybot starts up. - servercontrol (*) Basic server control. Takes care of initial setup as well as joining and leaving channels on the fly. - permissions (*) Provides access control for pybot. Most of the other modules access exported functions from this module to verify if users have given privilege. - help (*) Provides online help system. - options (*) Provides user access to the global options instance. Also takes care of maintaining persistent variables between runs, if any exists (pickle). - timer (*) Provides an API allowing modules to be called once in a while. - pong (*) Answers ping requests, and pings servers from time to time. - ignore Allows ignoring given users/channels/servers. - uptime Maintains and shows pybot uptime. - infopack Uses external databases to add knowledge to the bot. Each database may add its own trigger, default messages (when the trigger was sucessful, but no keys were found), help, etc. Available infopacks are acronyms (extracted from GNU vera), tcp/udp ports, and airports (both extracted from infobot). - messages Allow users to leave messages to named users. These messages will be sent when the named user gets into some channel or talks (usefull if he was just away). - forward Forwards messages between choosen channels and/or servers. - notes Allows maintaining general shared information about given topics. - eval Evaluates python expressions in protected environment. - repeat Repeat given message in selected server/channel once, or in given intervals. - freshmeat Check for new freshmeat releases and post them into selected channels/servers. - plock Provide simple colaborative locking mechanism (based on a system we used to have in Conectiva, that's why it's filesystem based, and have some specific requirements). - social Socialize pybot a little bit. - randnum Simple random number generator. - userdata Provides some general user data storage, and exports some functions providing this information for other modules. - xmlrpc Provides an API to easily export functions from any module through the XMLRPC protocol, including basic authentication information. Also implements a sendmsg() remote method, allowing external services to send messages and notices using pybot (demo client included); vim:st=4:sw=4:et |
From: Gustavo N. <nie...@us...> - 2003-05-12 20:42:53
|
Update of /cvsroot/pybot/pybot/data/infopacks In directory sc8-pr-cvs1:/tmp/cvs-serv6970/data/infopacks Modified Files: airport.info ports.info vera.info Log Message: Major work on pybot!! * modules/*: All modules moved to the new re matching system. * command.py: Removed old matching system. * modules/*: Pickling replaced by sqlite in all places were persistence was needed. * modules/*: All modules have inline help. * modules/*: All modules have permission help. * modules/infopack.py: Infopacks have help now. * *: Many method names changed to a better alternative. * options.py: Removed soft/hard relation. Now there's a single dict that might resist to reboots, if necessary. Notice that no standard module uses it for persistent options, since they use sqlite. * modules/example.py: Introduced basic sample module. * modules/soap.py: Obsoleted. Use xmlrpc instead. * scripts/pybotmsg.py: Added a basic xmlrpc client. * runner.py: Included other modules in the "default load" ones. * *: Other changes I probably forgot. Index: airport.info =================================================================== RCS file: /cvsroot/pybot/pybot/data/infopacks/airport.info,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** airport.info 2 Nov 2001 17:19:09 -0000 1.1.1.1 --- airport.info 12 May 2003 20:42:19 -0000 1.2 *************** *** 4,7 **** --- 4,8 ---- # information about infobot at http://www.infobot.org. # + H:This infopack provides a database of airport locations around the world. You can ask for an airport location using "airport <code>". T:(?:what|where)(?:'s|\s+is)\s+(?:the\s+)?airport\s+(?:code\s+)?([a-z]{3})\s*(?:!*\?[!?]*)?$ T:airport\s+([a-zA-Z]{3})\s*(?:!*\?[!?]*)?$ Index: ports.info =================================================================== RCS file: /cvsroot/pybot/pybot/data/infopacks/ports.info,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** ports.info 2 Nov 2001 17:19:21 -0000 1.1.1.1 --- ports.info 12 May 2003 20:42:19 -0000 1.2 *************** *** 4,7 **** --- 4,8 ---- # information about infobot at http://www.infobot.org. # + H:This infopack provides a database of port numbers. You can check what service is usually provided in a port number using "port <num>". T:what(?:'s|\s+is)\s+(?:the\s+)?port\s+(?:number\s+)?([0-9]+)(?:\s+for)\s*(?:!*\?[!?]*)?$ T:port\s+(\d+)[!?.]*$ Index: vera.info =================================================================== RCS file: /cvsroot/pybot/pybot/data/infopacks/vera.info,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** vera.info 2 Nov 2001 17:20:19 -0000 1.1.1.1 --- vera.info 12 May 2003 20:42:19 -0000 1.2 *************** *** 7,10 **** --- 7,11 ---- # ftp://ftp.gnu.org/gnu/vera # + H:This infopack provides the VERA database of acronyms. You can check for a given a acronym using "acronym <acronym>". T:acronym\s+(\w+)\s*\?*$ D:t:No acronym for that. |
From: Gustavo N. <nie...@us...> - 2003-05-12 20:42:52
|
Update of /cvsroot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv6970 Modified Files: ChangeLog TODO pybot.py Log Message: Major work on pybot!! * modules/*: All modules moved to the new re matching system. * command.py: Removed old matching system. * modules/*: Pickling replaced by sqlite in all places were persistence was needed. * modules/*: All modules have inline help. * modules/*: All modules have permission help. * modules/infopack.py: Infopacks have help now. * *: Many method names changed to a better alternative. * options.py: Removed soft/hard relation. Now there's a single dict that might resist to reboots, if necessary. Notice that no standard module uses it for persistent options, since they use sqlite. * modules/example.py: Introduced basic sample module. * modules/soap.py: Obsoleted. Use xmlrpc instead. * scripts/pybotmsg.py: Added a basic xmlrpc client. * runner.py: Included other modules in the "default load" ones. * *: Other changes I probably forgot. Index: ChangeLog =================================================================== RCS file: /cvsroot/pybot/pybot/ChangeLog,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** ChangeLog 9 May 2003 21:32:05 -0000 1.13 --- ChangeLog 12 May 2003 20:42:18 -0000 1.14 *************** *** 1,2 **** --- 1,22 ---- + 2003-05-12 Gustavo Niemeyer <nie...@co...> + * *: Major work on pybot!! + * modules/*: All modules moved to the new re matching system. + * command.py: Removed old matching system. + * modules/*: Pickling replaced by sqlite in all places were + persistence was needed. + * modules/*: All modules have inline help. + * modules/*: All modules have permission help. + * modules/infopack.py: Infopacks have help now. + * *: Many method names changed to a better alternative. + * options.py: Removed soft/hard relation. Now there's a single + dict that might resist to reboots, if necessary. Notice that + no standard module uses it for persistent options, since they + use sqlite. + * modules/example.py: Introduced basic sample module. + * modules/soap.py: Obsoleted. Use xmlrpc instead. + * scripts/pybotmsg.py: Added a basic xmlrpc client. + * runner.py: Included other modules in the "default load" ones. + * *: Other changes I probably forgot. + 2003-05-09 Gustavo Niemeyer <nie...@co...> * modules/userdata.py,modules/permission.py: A much better userdata Index: TODO =================================================================== RCS file: /cvsroot/pybot/pybot/TODO,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** TODO 9 May 2003 20:18:36 -0000 1.5 --- TODO 12 May 2003 20:42:18 -0000 1.6 *************** *** 4,26 **** - A better website for pybot. - - Include every module in the online help system. - - Adapt distutils classes to install every necessary file in their respective directories. - - Finish the conversion of msg.match to re.match and remove msg.match from - the code. - - Develop a README explaining how to do the basic setup of pybot. ! - Remove the parameter from __loadmodule() and __unloadmodule__(), and convert ! them to use a general "mod" name for the instance. ! ! - Cross identification between servers. ! ! - Include help topics when registering a help entry. ! ! - Include help for permissions. ! ! - Perhaps move all option system to sqlite. --- 4,13 ---- - A better website for pybot. - Adapt distutils classes to install every necessary file in their respective directories. - Develop a README explaining how to do the basic setup of pybot. ! - Cross identification between servers (is this useful?). + - Setup pybot nick when connecting. Index: pybot.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pybot.py 9 May 2003 20:18:36 -0000 1.3 --- pybot.py 12 May 2003 20:42:18 -0000 1.4 *************** *** 1,5 **** #!/usr/bin/python # ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,5 ---- #!/usr/bin/python # ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. |
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv6970/pybot/modules Modified Files: __init__.py eval.py forward.py freshmeat.py help.py ignore.py infopack.py log.py messages.py modulecontrol.py notes.py options.py permission.py plock.py pong.py randnum.py repeat.py servercontrol.py social.py testadora.py threadedexample.py timer.py uptime.py userdata.py xmlrpc.py Added Files: example.py Removed Files: soap.py Log Message: Major work on pybot!! * modules/*: All modules moved to the new re matching system. * command.py: Removed old matching system. * modules/*: Pickling replaced by sqlite in all places were persistence was needed. * modules/*: All modules have inline help. * modules/*: All modules have permission help. * modules/infopack.py: Infopacks have help now. * *: Many method names changed to a better alternative. * options.py: Removed soft/hard relation. Now there's a single dict that might resist to reboots, if necessary. Notice that no standard module uses it for persistent options, since they use sqlite. * modules/example.py: Introduced basic sample module. * modules/soap.py: Obsoleted. Use xmlrpc instead. * scripts/pybotmsg.py: Added a basic xmlrpc client. * runner.py: Included other modules in the "default load" ones. * *: Other changes I probably forgot. --- NEW FILE: example.py --- # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. # # pybot is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # pybot is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with pybot; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pybot import mm, hooks, options, db import time import re HELP = """ This is a module implementation showing a basic but complete module to serve as reference for other modules. It implements the command "hello (world|irc)". You will need the "example" permission to use that. """ PERM_EXAMPLE = """ The "example" permission allows users to access commands in the "example" module. For more information, check "help example". """ class Example: def __init__(self): hooks.register("Message", self.message) # hello (world|irc) self.re1 = re.compile(r"hello\s+(?P<what>world|irc)\s*[.!]*$", re.I) mm.register_help(r"example", HELP, "example") mm.register_perm("example", PERM_EXAMPLE) # This is a volatile variable which will be reset once pybot # reboots, but won't be lost if pybot reloads this module. Use # "show option Test.firstload" to check it. #firstload = options.get("Test.firstload", [int(time.time())]) # This is a persistent variable which will resist even if # pybot dies. Notice that no module in the standard module set # is using this kind of persistence (they use sqlite instead), # and if no module uses it, the "memory" file is transparently # not saved. #loads = options.get("Test.loads", [1], reboot=1) #loads[0] += 1 # This is a simple way of doing the same thing with the sqlite # dict system. It is useful for simple variables like this. #loads = int(db["loads"] or 0) #loads += 1 #db["loads"] = loads # And this is a more complex one, saving the load time as well # ('num' wasn't needed in this case since we could use the number # of entries in the table, but was included to show a table with # more than one field). #db.table("test", "num,timestamp") #cursor = db.cursor() #cursor.execute("select max(num) from test") #row = cursor.fetchone() #if row[0]: # loads = int(row[0])+1 #else: # loads = 1 #cursor.execute("insert into test values (%s,%s)", # loads, int(time.time())) def unload(self): hooks.unregister("Message", self.message) mm.unregister_help(HELP) mm.unregister_perm(PERM_EXAMPLE) def message(self, msg): if not msg.forme: return None m = self.re1.match(msg.line) if m: if mm.hasperm(msg, "example"): what = m.group("what") msg.answer("%:", "The", what, "welcomes you", [(",", "/"), None], [".", "!"]) else: msg.answer("%:", ["You have no permission for that", "You are not allowed to do this"], [".", "!"]) return 0 def __loadmodule__(): global mod mod = Example() def __unloadmodule__(): global mod mod.unload() del mod # vim:ts=4:sw=4:et Index: __init__.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/__init__.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** __init__.py 4 Dec 2001 00:57:38 -0000 1.2 --- __init__.py 12 May 2003 20:42:20 -0000 1.3 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. Index: eval.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/eval.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** eval.py 5 May 2003 17:42:10 -0000 1.3 --- eval.py 12 May 2003 20:42:20 -0000 1.4 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 21,26 **** import re class Eval: ! def __init__(self, bot): hooks.register("Message", self.message) self.dict = {} --- 21,44 ---- import re + HELP = """ + The "eval <expr>" command allows you to evaluate expressions + using the python evaluation mechanism. The following functions are + currently available: map, zip, len, min, max, chr, ord, abs, hex, int, + oct, list, long, float, round, tuple, reduce, filter, coerce, plus all + methods in the 'math' method. For more information on these functions, + consult the Python manual. + """,""" + This command depends on the "eval" permission. Notice that a malicious + user is able to hang me using this command, so no untrusted users should + have this permission. + """ + + PERM_EVAL = """ + This permission allows users to use the "eval" command. For more + information send me "help eval". + """ + class Eval: ! def __init__(self): hooks.register("Message", self.message) self.dict = {} *************** *** 52,86 **** # Match 'eval <expr>[!|.]' self.re1 = re.compile(r"eval\s+(?P<expr>.*?)[!.]*$") def unload(self): hooks.unregister("Message", self.message) def message(self, msg): ! var = [] ! if msg.forme: ! m = self.re1.match(msg.line) ! if m: ! if mm.hasperm(0, msg.server.servername, msg.target, msg.user, "eval"): ! try: ! answer = str(eval(m.group("expr"), self.dict)) ! except: ! msg.answer("%:", ["Can't evaluate this", "There's something wrong with this expression"], [".", "!"]) ! else: ! if len(answer) > 255: ! msg.answer("%:", "Sorry, your answer is too long...") ! else: ! msg.answer("%:", str(answer)) else: ! msg.answer("%:", ["Sorry...", "Oops!", "Heh!"], "You don't have this power", [".", "!"]) ! return 0 ! def __loadmodule__(bot): ! global _eval ! _eval = Eval(bot) ! def __unloadmodule__(bot): ! global _eval ! _eval.unload() ! del _eval # vim:ts=4:sw=4:et --- 70,115 ---- # Match 'eval <expr>[!|.]' self.re1 = re.compile(r"eval\s+(?P<expr>.*?)[!.]*$") + + # eval[uate|uation] + mm.register_help("eval(?:uate|uation)?", HELP, "eval") + + mm.register_perm("eval", PERM_EVAL) def unload(self): hooks.unregister("Message", self.message) + mm.unregister_help(HELP) + mm.unregister_perm("eval") def message(self, msg): ! if not msg.forme: ! return None ! ! m = self.re1.match(msg.line) ! if m: ! if mm.hasperm(msg, "eval"): ! try: ! answer = str(eval(m.group("expr"), self.dict)) ! except: ! msg.answer("%:", ["Can't evaluate this", ! "There's something wrong with this " ! "expression"], [".", "!"]) else: ! if len(answer) > 255: ! msg.answer("%:", "Sorry, your answer is too long...") ! else: ! msg.answer("%:", str(answer)) ! else: ! msg.answer("%:", ["Sorry...", "Oops!"], ! "You don't have this power", [".", "!"]) ! return 0 ! def __loadmodule__(): ! global mod ! mod = Eval() ! def __unloadmodule__(): ! global mod ! mod.unload() ! del mod # vim:ts=4:sw=4:et Index: forward.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/forward.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** forward.py 20 Jun 2002 17:37:15 -0000 1.3 --- forward.py 12 May 2003 20:42:21 -0000 1.4 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 17,27 **** # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from pybot import mm, hooks, options, servers from string import join import re class Forward: ! def __init__(self, bot): ! self.data = options.gethard("Forward.data", []) hooks.register("Message", self.message_forward, 100) hooks.register("OutMessage", self.message_forward, 100) --- 17,46 ---- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from pybot import mm, hooks, servers, db from string import join import re + HELP = """ + You can make me forward messages between servers and/or channels using + "forward messages [for you] [from|on|at] (user|channel) <target>] + [(from|on) server <server>] to (user|channel) <target> [on server + <server>]". You may include a string to identify the origin of the + forwarded message appending "with (server|channel [and server]|<string>)" + to the message above. + """,""" + You can check what is being forwarded with "show forwards". The "forward" + permission is necessary to change or list forwards. + """ + + PERM_FORWARD = """ + The "forward" permission allows users to make me forward messages + between servers and/or channels, and to list what is being forwarded. + Check "help forward" for more information. + """ + class Forward: ! def __init__(self): ! db.table("forward", "fromserver,fromtarget,toserver,totarget," ! "flags,with") hooks.register("Message", self.message_forward, 100) hooks.register("OutMessage", self.message_forward, 100) *************** *** 34,42 **** hooks.register("Message", self.message) ! # Match 'forward messages [[(from|on|at) server <fromserver1>] | for you | [(from|on|at) [user|channel] <fromtarget>] [(from|on|at) server <fromserver2>]] to [user|channel] <totarget> [(on|at) server <toserver>] [with (server|channel [and server]|<withstring>)] [!|.]' ! self.re1 = re.compile(r"(?P<dont>do\s+not\s+|don't\s+)?forward\s+messages\s+(?:(?:(?:from\s+|on\s+|at\s+)server\s+(?P<fromserver1>\S+)\s+)|(?:(?P<foryou>for\s+you\s+)?(?:(?:from\s+|on\s+|at\s+)(?:channel\s+|user\s+)?(?P<fromtarget>\S+)\s+)?(?:(?:from\s+|on\s+|at\s+)(?:server\s+)?(?P<fromserver2>\S+)\s+)?))?to\s+(?:user\s+|channel\s+)?(?P<totarget>\S+)(?:\s+(?:on\s+|at\s+)server\s+(?P<toserver>\S+))?(?:\s+with(?:(?P<withserver1>\s+server)|(?P<withchannel>\s+channel)(?:\s+and\s+(?P<withserver2>server))?|(?P<withstring>\S+)))?\s*[!.]*$", re.I) ! # Match 'what['re| are] you forwarding [?]' ! self.re2 = re.compile(r"what(?:'re|\s+are)\s+you\s+forwarding\s*\?*$", re.I) def unload(self): --- 53,66 ---- hooks.register("Message", self.message) ! # forward messages [for you] [(from|on|at) [user|channel] <fromtarget>] [(from|on|at) server <fromserver>]] to [user|channel] <totarget> [(on|at) server <toserver>] [with (server|channel [and server]|<withstring>)] [!|.] ! self.re1 = re.compile(r"(?P<dont>do\s+not\s+|don't\s+)?forward\s+messages\s+(?P<foryou>for\s+you\s+)?(?:(?:from\s+|on\s+|at\s+)(?:channel\s+|user\s+)?(?P<fromtarget>\S+)\s+)?(?:(?:from\s+|on\s+|at\s+)(?:server\s+)?(?P<fromserver>\S+)\s+)?to\s+(?:user\s+|channel\s+)?(?P<totarget>\S+)(?:\s+(?:on\s+|at\s+)server\s+(?P<toserver>\S+))?(?:\s+with\s+(?P<withchannel>channel)?(?:\s+and\s+)?(?P<withserver>server)?(?P<withstring>\S+)?)?\s*$", re.I) ! # show forwards ! self.re2 = re.compile(r"show\s+forwards\s*$", re.I) ! ! # [message] forward[ing] ! mm.register_help("(?:message\s+)?forward(?:ing)?", HELP, "forward") ! ! mm.register_perm("forward", PERM_FORWARD) def unload(self): *************** *** 50,159 **** hooks.unregister("UserParted", self.parted_forward, 100) hooks.unregister("Message", self.message) def do_forward(self, server, target, nick, forme, before, after): ! for tuple in self.data: ! if (tuple[0]==None or tuple[0]==server.servername) and \ ! (tuple[1]==None or tuple[1]==target) and \ ! (not tuple[2] or forme): ! fwdserver = servers.get(tuple[3]) if fwdserver: s = nick ! if tuple[6]: ! s = s+"@"+tuple[6] else: ! with = tuple[5] ! if with&1: s = s+"@"+target ! if with&2: s = s+","+server.servername ! elif with&2: s = s+"@"+server.servername ! fwdserver.sendmsg(tuple[4], None, before+s+after, outhooks=0) ! def message_forward(self, msg): ! self.do_forward(msg.server, msg.target, msg.user.nick, msg.forme, "<", "> "+msg.rawline) def notice_forward(self, msg): ! self.do_forward(msg.server, msg.target, msg.user.nick, msg.forme, "-", "- "+msg.rawline) def ctcp_forward(self, msg): if msg.ctcp == "ACTION": ! self.do_forward(msg.server, msg.target, msg.user.nick, msg.forme, "* ", " "+msg.rawline) def joined_forward(self, server, target, user): ! self.do_forward(server, target, user.nick, 0, "--> ", " has joined") def parted_forward(self, server, target, user, reason): if reason: ! self.do_forward(server, target, user.nick, 0, "--> ", " has leaved: "+reason) else: ! self.do_forward(server, target, user.nick, 0, "--> ", " has leaved") def message(self, msg): ! var = [] ! if msg.forme: ! m = self.re1.match(msg.line) ! if m: ! if mm.hasperm(0, msg.server.servername, msg.target, msg.user, "forward"): ! foryou = m.group("foryou") != None ! fromtarget = m.group("fromtarget") ! fromserver = m.group("fromserver1") or m.group("fromserver2") ! totarget = m.group("totarget") ! toserver = m.group("toserver") or msg.server.servername ! with = 0 if m.group("withchannel"): ! with = with|1 ! if m.group("withserver1") or m.group("withserver2"): ! with = with|2 ! withstring = m.group("withstring") ! if m.group("dont"): ! try: ! self.data.remove((fromserver, fromtarget, foryou, toserver, totarget, with, withstring)) ! msg.answer("%:", ["Sure", "I'll not forward", "Of course", "No problems"], ["!", "."]) ! except ValueError: ! msg.answer("%:", ["Sorry, but", "Oops! I think", None], "I'm not forwarding any messages like this", [".", "!"]) else: ! self.data.append((fromserver, fromtarget, foryou, toserver, totarget, with, withstring)) ! msg.answer("%:", ["Sure", "I'll forward", "Right now", "Of course"], ["!", "."]) ! return 0 ! ! m = self.re2.match(msg.line) ! if m: ! if mm.hasperm(0, msg.server.servername, msg.target, msg.user, "listforward"): ! if self.data: ! for tuple in self.data: ! str = "I'm forwarding messages" ! if tuple[2]: ! str = str+" for me" ! if tuple[0] and tuple[1] and tuple[1] != msg.server.servername: ! str = str+" from "+tuple[1]+" at "+tuple[0] ! elif tuple[1]: ! str = str+" from "+tuple[1] ! elif tuple[0]: ! str = str+" from server "+tuple[0] ! str = str+" to "+tuple[4] ! if tuple[3] and tuple[3] != msg.server.servername: ! str = str+" at "+tuple[3] ! if tuple[5]==3: ! str = str+" with channel and server" ! elif tuple[5]&1: ! str = str+" with channel" ! elif tuple[5]&2: ! str = str+" with server" ! elif tuple[6]: ! str = str+" with "+tuple[6] ! msg.answer("%:", str, [".", "!"]) else: ! msg.answer("%:", ["Sir,", None], "I'm not forwarding anything", ["!", "."]) ! return 0 ! def __loadmodule__(bot): ! global forward ! forward = Forward(bot) ! def __unloadmodule__(bot): ! global forward ! forward.unload() ! del forward # vim:ts=4:sw=4:et --- 74,245 ---- hooks.unregister("UserParted", self.parted_forward, 100) hooks.unregister("Message", self.message) + mm.unregister_help(HELP) + mm.unregister_perm("forward") def do_forward(self, server, target, nick, forme, before, after): ! cursor = db.cursor() ! cursor.execute("select * from forward") ! for row in cursor.fetchall(): ! if (row.fromserver is None or ! row.fromserver == server.servername) and \ ! (row.fromtarget is None or row.fromtarget == target) and \ ! (forme or "f" in row.flags): ! fwdserver = servers.get(row.toserver) if fwdserver: s = nick ! if row.with.startswith(":"): ! s = s+"@"+row.with[1:] else: ! if "c" in row.with: s = s+"@"+target ! if "s" in row.with: s = s+","+server.servername ! elif "s" in row.with: s = s+"@"+server.servername ! fwdserver.sendmsg(row.totarget, None, before+s+after, ! outhooks=0) ! def message_forward(self, msg): ! self.do_forward(msg.server, msg.target, msg.user.nick, msg.forme, ! "<", "> "+msg.rawline) def notice_forward(self, msg): ! self.do_forward(msg.server, msg.target, msg.user.nick, msg.forme, ! "-", "- "+msg.rawline) def ctcp_forward(self, msg): if msg.ctcp == "ACTION": ! self.do_forward(msg.server, msg.target, msg.user.nick, msg.forme, ! "* ", " "+msg.rawline) def joined_forward(self, server, target, user): ! self.do_forward(server, target, user.nick, 0, ! "--> ", " has joined") def parted_forward(self, server, target, user, reason): if reason: ! self.do_forward(server, target, user.nick, 0, ! "--> ", " has leaved: "+reason) else: ! self.do_forward(server, target, user.nick, 0, ! "--> ", " has leaved") def message(self, msg): ! if not msg.forme: ! return None ! ! m = self.re1.match(msg.line) ! if m: ! if mm.hasperm(msg, "forward"): ! foryou = m.group("foryou") != None ! fromtarget = m.group("fromtarget") ! fromserver = m.group("fromserver") ! totarget = m.group("totarget") ! toserver = m.group("toserver") or msg.server.servername ! withstring = m.group("withstring") ! if withstring: ! with = ":"+withstring ! else: ! with = "" if m.group("withchannel"): ! with += "c" ! if m.group("withserver"): ! with += "s" ! flags = "" ! if foryou: ! flags += "f" ! cursor = db.cursor() ! where = [] ! wargs = [] ! if fromserver: ! where.append("fromserver=%s") ! wargs.append(fromserver) ! else: ! where.append("fromserver isnull") ! if fromtarget: ! where.append("fromtarget=%s") ! wargs.append(fromtarget) ! else: ! where.append("fromtarget isnull") ! where.extend(["toserver=%s", "totarget=%s", ! "flags=%s", "with=%s"]) ! wstr = " and ".join(where) ! wargs.extend([toserver, totarget, flags, with]) ! if m.group("dont"): ! cursor.execute("delete from forward where "+wstr, *wargs) ! if not cursor.rowcount: ! msg.answer("%:", ["Sorry, but", ! "Oops! I think", None], ! "I'm not forwarding any messages " ! "like this", [".", "!"]) else: ! msg.answer("%:", ["Sure", "I won't forward", ! "Of course", "No problems"], ! ["!", "."]) ! else: ! cursor.execute("select * from forward where "+wstr, ! *wargs) ! if cursor.rowcount: ! msg.answer("%:", "I'm already forwarding this.") else: ! cursor.execute("insert into forward values " ! "(%s,%s,%s,%s,%s,%s)", ! fromserver, fromtarget, ! toserver, totarget, flags, with) ! msg.answer("%:", ["Sure", "I'll forward", ! "Right now", "Of course"], ! ["!", "."]) ! return 0 ! ! m = self.re2.match(msg.line) ! if m: ! if mm.hasperm(msg, "forward"): ! cursor = db.cursor() ! cursor.execute("select * from forward") ! rows = cursor.fetchall() ! if not rows: ! msg.answer("%:", "I'm not forwarding anything", ["!", "."]) ! return 0 ! ! for row in rows: ! str = "I'm forwarding messages" ! if "f" in row.flags: ! str += " for me" ! if row.fromserver and row.fromtarget: ! str += " from " ! str += row.fromtarget ! str += " on server " ! str += msg.fromserver ! elif row.fromtarget: ! str += " from " ! str += row.fromtarget ! elif row.fromserver: ! str += " from server " ! str += row.fromserver ! str += " to " ! str += row.totarget ! if row.toserver and row.toserver != msg.server.servername: ! str += " on server " ! str += row.toserver ! if row.with.startswith(":"): ! str += " with " ! str += row.with[1:] ! elif "c" in row.with and "s" in row.with: ! str = str+" with channel and server" ! elif "c" in row.with: ! str = str+" with channel" ! elif "s" in row.with: ! str = str+" with server" ! msg.answer("%:", str, ".") ! return 0 ! def __loadmodule__(): ! global mod ! mod = Forward() ! def __unloadmodule__(): ! global mod ! mod.unload() ! del mod # vim:ts=4:sw=4:et Index: freshmeat.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/freshmeat.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** freshmeat.py 9 May 2003 21:32:06 -0000 1.7 --- freshmeat.py 12 May 2003 20:42:21 -0000 1.8 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 17,21 **** # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from pybot import mm, hooks, options, servers, config import urllib import thread --- 17,21 ---- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from pybot import mm, hooks, servers, config, db import urllib import thread *************** *** 23,35 **** import re ! HELP = [ ! ("""\ ! You may tell me which channels/users I have to notify of freshmeat news \ ! with "[don't] show freshmeat news [(on|to) [channel|user] <target> [on \ ! server <server>]]".\ ! """,)] class Freshmeat: ! def __init__(self, bot): self.url = config.get("freshmeat", "url") if config.has_option("freshmeat", "proxy"): --- 23,41 ---- import re ! HELP = """ ! You may tell me which channels/users I have to notify of freshmeat news ! with "[don't] show freshmeat news [(on|to) [channel|user] <target> [on ! server <server>]]". The "freshmeat" permission is necessary to change ! these settings. ! """ ! ! PERM_FRESHMEAT = """ ! The "freshmeat" permission allows you to change what servers and ! channels will receive freshmeat news. Check "help freshmeat" for ! more information. ! """ class Freshmeat: ! def __init__(self): self.url = config.get("freshmeat", "url") if config.has_option("freshmeat", "proxy"): *************** *** 38,59 **** self.proxy = None self.interval = config.getint("freshmeat", "interval") ! self.newslast = options.gethard("Freshmeat.newslast", [None]) ! self.newstargets = options.gethard("Freshmeat.newstargets", []) ! self.newstargets_lock = thread.allocate_lock() self.fetch_lock = thread.allocate_lock() hooks.register("Message", self.message) ! mm.hooktimer(0, self.interval*60, self.checknews, ()) ! # Match '[don[']t|do not] show freshmeat news [(to|on|at|for) [channel|user] <target> [[on|at] server <server>]] [!|.]' self.re1 = re.compile(r"(?P<dont>don'?t\s+|do\s+not\s+)?show\s+freshmeat\s+news(?:\s+(?:to|on|at|for)(?:\s+channel|\s+user)?\s+(?P<target>\S+)(?:(?:\s+on|\s+at)?\s+server\s+(?P<server>\S+?))?)?\s*[!.]*$", re.I) # freshmeat [news] ! mm.register_help(0, "freshmeat(?:\s+news)?", HELP, "freshmeat") def unload(self): hooks.unregister("Message", self.message) ! mm.unhooktimer(0, self.interval*60, self.checknews, ()) ! ! mm.unregister_help(0, HELP) def shownews(self, newslist): --- 44,69 ---- self.proxy = None self.interval = config.getint("freshmeat", "interval") ! ! db.table("freshmeat", "servername,target") ! self.fetch_lock = thread.allocate_lock() + hooks.register("Message", self.message) ! ! mm.hooktimer(self.interval*60, self.checknews, ()) ! # [don[']t|do not] show freshmeat news [(to|on|at|for) [channel|user] <target> [[on|at] server <server>]] self.re1 = re.compile(r"(?P<dont>don'?t\s+|do\s+not\s+)?show\s+freshmeat\s+news(?:\s+(?:to|on|at|for)(?:\s+channel|\s+user)?\s+(?P<target>\S+)(?:(?:\s+on|\s+at)?\s+server\s+(?P<server>\S+?))?)?\s*[!.]*$", re.I) # freshmeat [news] ! mm.register_help("freshmeat(?:\s+news)?", HELP, "freshmeat") ! ! mm.register_perm("freshmeat", PERM_FRESHMEAT) def unload(self): hooks.unregister("Message", self.message) ! mm.unhooktimer(self.interval*60, self.checknews, ()) ! mm.unregister_help(HELP) ! mm.unregister_perm("freshmeat") def shownews(self, newslist): *************** *** 66,75 **** first = 0 newsmsg = newsmsg+news[0] ! self.newstargets_lock.acquire() ! for target in self.newstargets: ! server = servers.get(target[0]) if server: ! server.sendmsg(target[1], None, "Freshmeat news:", newsmsg, notice=1) ! self.newstargets_lock.release() def fetchnews(self): --- 76,86 ---- first = 0 newsmsg = newsmsg+news[0] ! cursor = db.cursor() ! cursor.execute("select * from freshmeat") ! for row in cursor.fetchall(): ! server = servers.get(row.servername) if server: ! server.sendmsg(row.target, None, "Freshmeat news:", ! newsmsg, notice=1) def fetchnews(self): *************** *** 84,87 **** --- 95,101 ---- else: newslist = [] + # We're in a thread. Get our own database object. + localdb = db.copy() + last = localdb["freshmeat.last"] while 1: news_name = string.rstrip(url.readline()) *************** *** 93,102 **** news_name = news_name[:-defstrlen] news_tuple = (news_name, news_time, news_url) ! if not (news_name and news_time and news_url) or news_tuple == self.newslast[0]: break newslist.append(news_tuple) url.close() if newslist: ! self.newslast[0] = newslist[0] newslist.reverse() self.shownews(newslist) --- 107,116 ---- news_name = news_name[:-defstrlen] news_tuple = (news_name, news_time, news_url) ! if not (news_name and news_time and news_url) or str(news_tuple) == last: break newslist.append(news_tuple) url.close() if newslist: ! localdb["freshmeat.last"] = str(newslist[0]) newslist.reverse() self.shownews(newslist) *************** *** 104,147 **** def checknews(self): ! if self.newstargets and self.fetch_lock.acquire(0): thread.start_new_thread(self.fetchnews, ()) def message(self, msg): ! if msg.forme: ! m = self.re1.match(msg.line) ! if m: ! if mm.hasperm(0, msg.server.servername, msg.target, msg.user, "freshmeatnews"): ! target = m.group("target") or msg.target ! servername = m.group("server") or msg.server.servername ! tuple = (servername, target) ! if not m.group("dont"): ! try: ! self.newstargets.index(tuple) ! except ValueError: ! self.newstargets.append(tuple) ! msg.answer("%:", ["Sure", "I'll show", "Of course"], ["!", ", sir!"]) ! else: ! msg.answer("%:", ["Oops!", "Sorry!", "Nope."], "I'm already showing news for this target", ["!", "."]) else: ! self.newstargets_lock.acquire() ! try: ! self.newstargets.remove(tuple) ! except ValueError: ! msg.answer("%:", ["Oops!", "Sorry!", "Nope."], "I'm not showing news for this target", ["!", "."]) ! else: ! msg.answer("%:", ["Sure", "I won't show", "Of course"], ["!", "."]) ! self.newstargets_lock.release() else: ! msg.answer("%:", ["You can't", "You're not allowed to", "You're not good enough to"], ["do this", "You can't change freshmeat news settings"], ["!", "."]) ! return 0 ! def __loadmodule__(bot): ! global freshmeat ! freshmeat = Freshmeat(bot) ! def __unloadmodule__(bot): ! global freshmeat ! freshmeat.unload() ! del freshmeat # vim:ts=4:sw=4:et --- 118,175 ---- def checknews(self): ! cursor = db.cursor() ! cursor.execute("select * from freshmeat") ! if cursor.rowcount and self.fetch_lock.acquire(0): thread.start_new_thread(self.fetchnews, ()) def message(self, msg): ! if not msg.forme: ! return None ! ! m = self.re1.match(msg.line) ! if m: ! if mm.hasperm(msg, "freshmeat"): ! target = m.group("target") or msg.target ! servername = m.group("server") or msg.server.servername ! cursor = db.cursor() ! if not m.group("dont"): ! cursor.execute("select * from freshmeat where " ! "servername=%s and target=%s", ! servername, target) ! if cursor.rowcount: ! msg.answer("%:", ["Oops!", "Sorry!", "Nope."], ! "I'm already showing news for " ! "this target", ["!", "."]) else: ! cursor.execute("insert into freshmeat values (%s,%s)", ! servername, target) ! msg.answer("%:", ["Sure", "I'll show", ! "Of course"], ["!", "."]) else: ! cursor.execute("delete from freshmeat where " ! "servername=%s and target=%s", ! servername, target) ! if not cursor.rowcount: ! msg.answer("%:", ["Oops!", "Sorry!", "Nope."], ! "I'm not showing news for " ! "this target", ["!", "."]) ! else: ! msg.answer("%:", ["Sure", "I won't show", ! "Of course"], ["!", "."]) ! else: ! msg.answer("%:", ["You can't", "You're not allowed to", ! "You're not good enough to"], ! ["do this", ! "change freshmeat settings"], ["!", "."]) ! return 0 ! def __loadmodule__(): ! global mod ! mod = Freshmeat() ! def __unloadmodule__(): ! global mod ! mod.unload() ! del mod # vim:ts=4:sw=4:et Index: help.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/help.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** help.py 9 May 2003 21:32:06 -0000 1.4 --- help.py 12 May 2003 20:42:21 -0000 1.5 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 18,40 **** from pybot import hooks, mm, options ! from types import ListType import re ! HELP = [ ! ("""\ ! You may ask for help using "[show] help [about] <something>".\ ! """,) ! ] class Help: ! def __init__(self, bot): ! self.data = options.getsoft("Help.data", []) ! self.triggers = options.getsoft("Help.triggers", {}) mm.register("register_help", self.mm_register_help) mm.register("unregister_help", self.mm_unregister_help) hooks.register("Message", self.message) # [show] help [about] <keyword> self.re1 = re.compile(r"(?:show\s+)?help(?:\s+about)?(?:\s+(?P<something>.+?))?\s*[.!]*$", re.I) def unload(self): --- 18,46 ---- from pybot import hooks, mm, options ! from types import ListType, TupleType import re ! HELP = """ ! You may ask for help using "[show] help [about] <something>". ! """ ! ! PERM_HELP = """ ! I'll only allow users with the "help" permission to ask for help. ! """ class Help: ! def __init__(self): ! self.data = options.get("Help.data", []) ! self.perm = options.get("Help.perm", {}) mm.register("register_help", self.mm_register_help) mm.register("unregister_help", self.mm_unregister_help) + mm.register("register_perm", self.mm_register_perm) + mm.register("unregister_perm", self.mm_unregister_perm) hooks.register("Message", self.message) # [show] help [about] <keyword> self.re1 = re.compile(r"(?:show\s+)?help(?:\s+about)?(?:\s+(?P<something>.+?))?\s*[.!]*$", re.I) + + self.mm_register_perm("help", PERM_HELP) def unload(self): *************** *** 42,78 **** mm.unregister("register_help") mm.unregister("unregister_help") def message(self, msg): ! if msg.forme: ! m = self.re1.match(msg.line) ! if m: ! if mm.hasperm(0, msg.server.servername, msg.target, msg.user, "help"): ! something = m.group("something") ! if something: ! found = 0 ! for pattern, text, triggers in self.data: ! if pattern.match(something): ! found = 1 for line in text: ! msg.answer("%:", *line) ! else: ! found = 1 ! for line in HELP: ! msg.answer("%:", *line) ! alltriggers = [] ! for pattern, text, triggers in self.data: ! alltriggers.extend(triggers) ! if alltriggers: ! alltriggers.sort() ! s = "At least the following help items are known: " ! s += ", ".join(alltriggers) ! msg.answer("%:", s) ! if not found: ! msg.answer("%:", ["No", "Sorry, no", "Sorry, but there's no"], "help about that", [".", "!"]) else: ! msg.answer("%:", ["Sorry, you", "You"], ["can't", "are not allowed to"], "ask for help", [".", "!"]) ! return 0 ! def mm_register_help(self, defret, pattern, text, triggers=None): if not triggers: triggers = [] --- 48,100 ---- mm.unregister("register_help") mm.unregister("unregister_help") + mm.unregister("register_perm") + mm.unregister("unregister_perm") + self.mm_unregister_perm("help") def message(self, msg): ! if not msg.forme: ! return None ! ! m = self.re1.match(msg.line) ! if m: ! if mm.hasperm(msg, "help"): ! something = m.group("something") ! if something: ! found = 0 ! for pattern, text, triggers in self.data: ! match = pattern.match(something) ! if match: ! found = 1 ! if callable(text): ! text(msg, match) ! elif type(text) in (ListType, TupleType): for line in text: ! line = line.replace("\n", " ").strip() ! msg.answer("%:", line) ! else: ! text = text.replace("\n", " ").strip() ! msg.answer("%:", text) else: ! found = 1 ! msg.answer("%:", HELP.replace("\n", " ").strip()) ! alltriggers = [] ! for pattern, text, triggers in self.data: ! alltriggers.extend(triggers) ! if alltriggers: ! alltriggers.sort() ! s = "At least the following help topics are known: " ! s += ", ".join(alltriggers) ! msg.answer("%:", s) ! if not found: ! msg.answer("%:", ["No", "Sorry, no", ! "Sorry, but there's no"], ! "help about that", [".", "!"]) ! else: ! msg.answer("%:", ["Sorry, you", "You"], ! ["can't", "are not allowed to"], ! "ask for help", [".", "!"]) ! return 0 ! def mm_register_help(self, pattern, text, triggers=None): if not triggers: triggers = [] *************** *** 81,99 **** self.data.append((re.compile(pattern, re.I), text, triggers)) ! def mm_unregister_help(self, defret, text): for i in range(len(self.data)-1,-1,-1): if self.data[i][1] == text: del self.data[i] # Make sure it is loaded first to let mm.register_help() # available to everyone. __loadlevel__ = 90 ! ! def __loadmodule__(bot): global help ! help = Help(bot) ! def __unloadmodule__(bot): global help help.unload() --- 103,129 ---- self.data.append((re.compile(pattern, re.I), text, triggers)) ! def mm_unregister_help(self, text): for i in range(len(self.data)-1,-1,-1): if self.data[i][1] == text: del self.data[i] + def mm_register_perm(self, perm, text): + self.perm[perm] = text + + def mm_unregister_perm(self, perm): + try: + del self.perm[perm] + except KeyError: + pass + # Make sure it is loaded first to let mm.register_help() # available to everyone. __loadlevel__ = 90 ! def __loadmodule__(): global help ! help = Help() ! def __unloadmodule__(): global help help.unload() Index: ignore.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/ignore.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ignore.py 20 Jun 2002 17:37:16 -0000 1.3 --- ignore.py 12 May 2003 20:42:21 -0000 1.4 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 17,111 **** # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from pybot import mm, hooks, options ! from pybot.user import User class Ignore: ! def __init__(self, bot): ! self.ignoredata = options.gethard("Ignore.ignore", []) hooks.register("Message", self.message_ignore, 200) hooks.register("Message", self.message) def unload(self): hooks.unregister("Message", self.message_ignore, 200) hooks.unregister("Message", self.message) def message_ignore(self, msg): if self.isignored(msg.server.servername, msg.target, msg.user) and \ ! not mm.hasperm(0, msg.server.servername, msg.target, msg.user, None): return -1 def message(self, msg): ! var = [] ! if msg.match(var, 5, "%", "ignore", [("user", 0, "~"), None], [(["on", "at", None], [(1, "~this", "channel"), ("channel", 2, "^[#&+!][^,^G]+$")]), None], [(["on", "at", None], [(3, "~this", "server"), ("server", 4, "~")]), None], ["!", ".", None]): ! if mm.hasperm(0, msg.server.servername, msg.target, msg.user, "ignore"): ! if var[0] or var[1] or var[2] or var[3] or var[4]: ! if var[1]: ! channel = msg.target ! server = msg.server.servername ! else: ! channel = var[2] ! if var[3]: ! server = msg.server.servername ! else: ! server = var[4] ! if var[0]: ! user = User() ! user.setstring(var[0]) else: ! user = None ! self.ignore(server,channel,user) ! msg.answer("%:", ["Done!", "Ignored!", "No problems, sir!", "Ok, sir!"]) ! else: ! msg.answer("%:", ["Sorry, you", "Sir, you", "You"], ["can't ignore.", "don't have this power."]) ! return 0 ! if msg.match(var, 5, "%", "don't", "ignore", [("user", 0, "~"), None], [(["on", "at", None], [(1, "~this", "channel"), ("channel", 2, "^[#&+!][^,^G]+$")]), None], [(["on", "at", None], [(3, "~this", "server"), ("server", 4, "~")]), None], ["!", ".", None]): ! if mm.hasperm(0, msg.server.servername, msg.target, msg.user, "ignore"): ! if var[0] or var[1] or var[2] or var[3] or var[4]: ! if var[1]: ! channel = msg.target ! server = msg.server.servername else: ! channel = var[2] ! if var[3]: ! server = msg.server.servername ! else: ! server = var[4] ! if var[0]: ! user = User() ! user.setstring(var[0]) else: ! user = None ! self.dontignore(server,channel,user) ! msg.answer("%:", ["Done, sir!", "No problems!", "Ok!", "Right now!", "Right now, sir!"]) else: ! msg.answer("%:", ["Sorry, you", "Sir, you", "You"], "don't have this power.") return 0 ! def ignore(self, server, channel, user): ! self.ignoredata.append((server,channel,user)) ! def dontignore(self, server, channel, user): ! for tup in self.ignoredata: ! if (tup[0] == None or tup[0] == server) and \ ! (tup[1] == None or tup[1] == channel) and \ ! (tup[2] == None or user.match(tup[2].nick, tup[2].username, tup[2].host)): ! self.ignoredata.remove(tup) ! return 1 ! def isignored(self, server, channel, user): ! for tup in self.ignoredata: ! if (tup[0] == None or tup[0] == server) and \ ! (tup[1] == None or tup[1] == channel) and \ ! (tup[2] == None or user.match(tup[2].nick, tup[2].username, tup[2].host)): return 1 ! def __loadmodule__(bot): ! global ignore ! ignore = Ignore(bot) ! def __unloadmodule__(bot): ! global ignore ! ignore.unload() ! del ignore # vim:ts=4:sw=4:et --- 17,160 ---- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from pybot import mm, hooks, db ! import re ! ! HELP = """ ! You can make me ignore and unignore people sending me the message ! "[don't] ignore [user <user>] [on|at] [this channel|channel <channel>] ! [on|at] [this server|server <server>]. To do that, you must have the ! "ignore" permission. You may also give the "neverignore" permission ! to the people that should never be ignored, even if matching some ! ignore pattern. ! """ ! ! PERM_IGNORE = """ ! This permission allow users to change the ignore settings. For more ! information use "help ignore". ! """ ! ! PERM_NEVERIGNORE = """ ! People with the "neverignore" permission will never be ignored by ! me, even when they match some active ignore pattern. ! """ class Ignore: ! def __init__(self): ! db.table("ignore", "servername,target,userstr") ! hooks.register("Message", self.message_ignore, 200) hooks.register("Message", self.message) + + # [do not|don't] ignore [user <user>] [on|at] [this channel|channel <channel>] [on|at] [this server|server <server>] + self.re1 = re.compile(r"(?P<dont>do\s+not\s+|don't\s+)?ignore\s+(?:user\s+(?P<user>\S+?))?(?:(?:on\s+|at\s+)?(?:(?P<thischannel>this\s+channel)|channel\s+(?P<channel>\S+)))?(?:(?:on\s+|at\s+)?(?:(?P<thisserver>this\s+server)|server\s+(?P<server>\S+?)))?\s*$", re.I) + + # [un]ignore + mm.register_help(r"(?:un)?ignore", HELP, "ignore") + + mm.register_perm("ignore", PERM_IGNORE) + mm.register_perm("neverignore", PERM_NEVERIGNORE) def unload(self): hooks.unregister("Message", self.message_ignore, 200) hooks.unregister("Message", self.message) + mm.unregister_help(HELP) + mm.unregister_perm("ignore") + mm.unregister_perm("neverignore") def message_ignore(self, msg): if self.isignored(msg.server.servername, msg.target, msg.user) and \ ! not mm.hasperm(msg, "neverignore"): return -1 def message(self, msg): ! if not msg.forme: ! return None ! ! m = self.re1.match(msg.line) ! if m: ! if mm.hasperm(msg, "ignore"): ! userstr = m.group("user") ! if not filter(bool, m.groups()): ! return ! if m.group("thischannel"): ! target = msg.target ! servername = msg.server.servername ! else: ! target = m.group("channel") ! if m.group("thisserver"): ! servername = msg.server.servername else: ! servername = m.group("server") ! if not m.group("dont"): ! if self.ignore(servername, target, userstr): ! msg.answer("%:", ["Done", "Ignored", ! "No problems", "Ok"], [".", "!"]) else: ! msg.answer("%:", "I was already ignoring it", ! [".", "!"]) ! else: ! if self.dontignore(servername, target, userstr): ! msg.answer("%:", ["Done", "No problems", ! "Ok", "Right now"], [".", "!"]) else: ! msg.answer("%:", "I'm not ignoring it", [".", "!"]) else: ! msg.answer("%:", ["Sorry, you", "Oops, you", "You"], ! ["can't do this", "don't have this power"], ! [".", "!"]) return 0 ! def ignore(self, servername, target, userstr): ! cursor = db.cursor() ! existed = self.dontignore(servername, target, userstr, check=1) ! if existed: ! return 0 ! cursor.execute("insert into ignore values (%s,%s,%s)", ! servername, target, userstr) ! return 1 ! def dontignore(self, servername, target, userstr, check=0): ! where = [] ! wargs = [] ! if servername: ! where.append("servername=%s") ! wargs.append(servername) ! else: ! where.append("servername isnull") ! if target: ! where.append("target=%s") ! wargs.append(target) ! else: ! where.append("target isnull") ! if userstr: ! where.append("userstr=%s") ! wargs.append(userstr) ! else: ! where.append("userstr isnull") ! wstr = " and ".join(where) ! cursor = db.cursor() ! if not check: ! cursor.execute("delete from ignore where "+wstr, *wargs) ! else: ! cursor.execute("select * from ignore where "+wstr, *wargs) ! return bool(cursor.rowcount) ! def isignored(self, servername, target, user): ! cursor = db.cursor() ! cursor.execute("select * from ignore") ! for row in cursor.fetchall(): ! if (not row.servername or row.servername == servername) and \ ! (not row.target or row.target == target) and \ ! (not row.userstr or user.matchstr(row.userstr)): return 1 ! def __loadmodule__(): ! global mod ! mod = Ignore() ! def __unloadmodule__(): ! global mod ! mod.unload() ! del mod # vim:ts=4:sw=4:et Index: infopack.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/infopack.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** infopack.py 9 May 2003 21:32:06 -0000 1.4 --- infopack.py 12 May 2003 20:42:21 -0000 1.5 *************** *** 17,25 **** # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from pybot import config, options, hooks, mm from random import randrange import re import os class Info: def __init__(self, phrase="", action=0, notice=0, tonick=0): --- 17,42 ---- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from pybot import config, hooks, mm, db from random import randrange import re import os + HELP = """ + Infopacks are knowledge packages that you can plug to make me + provide some specific information to all users. To load some + infopack, put it in the infopack directory (check the configuration + file), and use the command "[load|reload|unload] infopack <name> + [in memory]" (the "infopackadmin" permission is needed). + """,""" + To show which infopacks are loaded, send me "show infopacks". You + can also ask for help about some specific infopack with "help infopack + <name>". + """ + + PERM_INFOPACKADMIN = """ + Users with the "infopackadmin" permission can change infopack + settings. Check "help infopack" for more informatino. + """ + class Info: def __init__(self, phrase="", action=0, notice=0, tonick=0): *************** *** 31,46 **** class Infopack: def __init__(self, filename): ! self.__filename = filename ! self.__info = {} ! self.__triggers = [] ! self.__masks = [] ! self.__defaults = [] ! def load(self): ! self.__info = {} ! self.__triggers = [] ! self.__masks = [] values = [] ! file = open(self.__filename) for line in file.xreadlines(): if line and line[0] != "#": --- 48,67 ---- class Infopack: def __init__(self, filename): ! self._filename = filename ! self._info = {} ! self._triggers = [] ! self._masks = [] ! self._defaults = [] ! self._help = [] ! ! def help(self): ! return self._help ! def load(self): ! self._info = {} ! self._triggers = [] ! self._masks = [] values = [] ! file = open(self._filename) for line in file.xreadlines(): if line and line[0] != "#": *************** *** 48,52 **** if values != []: values = [] ! self.__info[line[2:].rstrip()] = values elif line[0] == "V": value = line[2:].split(":", 1) --- 69,73 ---- if values != []: values = [] ! self._info[line[2:].rstrip()] = values elif line[0] == "V": value = line[2:].split(":", 1) *************** *** 55,84 **** elif line[0] == "T": pattern = re.compile(line[2:].rstrip(), re.I) ! self.__triggers.append(pattern) elif line[0] == "M": ! self.__masks.append(line[2:].rstrip()) elif line[0] == "D": value = line[2:].split(":", 1) value[1] = value[1].rstrip() ! self.__defaults.append(value) ... [truncated message content] |
From: Gustavo N. <nie...@us...> - 2003-05-12 20:42:25
|
Update of /cvsroot/pybot/pybot/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv6970/scripts Added Files: pybotmsg.py Log Message: Major work on pybot!! * modules/*: All modules moved to the new re matching system. * command.py: Removed old matching system. * modules/*: Pickling replaced by sqlite in all places were persistence was needed. * modules/*: All modules have inline help. * modules/*: All modules have permission help. * modules/infopack.py: Infopacks have help now. * *: Many method names changed to a better alternative. * options.py: Removed soft/hard relation. Now there's a single dict that might resist to reboots, if necessary. Notice that no standard module uses it for persistent options, since they use sqlite. * modules/example.py: Introduced basic sample module. * modules/soap.py: Obsoleted. Use xmlrpc instead. * scripts/pybotmsg.py: Added a basic xmlrpc client. * runner.py: Included other modules in the "default load" ones. * *: Other changes I probably forgot. --- NEW FILE: pybotmsg.py --- #!/usr/bin/python import xmlrpclib import sys # You'll probably want to "chmod 700" this script. AUTH = {"username": "<username>", "password": "<password>", "server": "irc.example.com", "target": "#channel"} PYBOT = "http://pybot.host:8460" if len(sys.argv) != 2: sys.exit("Usage: pybotmsg.py \"Message ...\"") proxy = xmlrpclib.ServerProxy(PYBOT) proxy.sendmsg(AUTH, sys.argv[1], 1) |
Update of /cvsroot/pybot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv6970/pybot Modified Files: __init__.py command.py hook.py main.py misc.py module.py option.py runner.py server.py sqlitedb.py user.py Log Message: Major work on pybot!! * modules/*: All modules moved to the new re matching system. * command.py: Removed old matching system. * modules/*: Pickling replaced by sqlite in all places were persistence was needed. * modules/*: All modules have inline help. * modules/*: All modules have permission help. * modules/infopack.py: Infopacks have help now. * *: Many method names changed to a better alternative. * options.py: Removed soft/hard relation. Now there's a single dict that might resist to reboots, if necessary. Notice that no standard module uses it for persistent options, since they use sqlite. * modules/example.py: Introduced basic sample module. * modules/soap.py: Obsoleted. Use xmlrpc instead. * scripts/pybotmsg.py: Added a basic xmlrpc client. * runner.py: Included other modules in the "default load" ones. * *: Other changes I probably forgot. Index: __init__.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/__init__.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** __init__.py 8 May 2003 19:11:34 -0000 1.5 --- __init__.py 12 May 2003 20:42:20 -0000 1.6 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. Index: command.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/command.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** command.py 4 Dec 2001 00:57:38 -0000 1.2 --- command.py 12 May 2003 20:42:20 -0000 1.3 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 17,27 **** # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from types import TupleType, ListType, IntType ! from string import split, lower from pybot.user import User import re - class MatchError: pass - class Command: re = re.compile("(?::(\\S*) )?(\\w+) ((\\S+) :(?:\01(\\w+) )?((?:\\W*(\\w+)\\W*\\s)?(.*?))(?:\01)?|.*)$") --- 17,24 ---- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from string import split from pybot.user import User import re class Command: re = re.compile("(?::(\\S*) )?(\\w+) ((\\S+) :(?:\01(\\w+) )?((?:\\W*(\\w+)\\W*\\s)?(.*?))(?:\01)?|.*)$") *************** *** 140,319 **** self.server.sendmsg(self.answertarget, self.user.nick, *params, **kw) - # FIXME: These should be removed as soon as all modules - # start using regexps - def match(self, var, varn, *pattern): - if varn != 0: - var[:] = [None]*varn - try: - n = self._match(var, 0, self.msg, pattern) - except MatchError: - return None - if n == len(self.msg): - return 1 - - def _match(self, var, n, query, pattern): - l = len(query) - lp = len(pattern) - i = 0 - while i < lp: - tok = pattern[i] - if type(tok) == TupleType: - n = self._match(var, n, query, tok) - elif type(tok) == ListType: - n = self._matchany(var, n, query, tok) - elif n >= l: - raise MatchError - elif type(tok) == IntType: - pos = tok - i = i+1 - tok = pattern[i] - if tok == "~": - var[pos] = query[n] - elif tok[0] == "~": - if lower(query[n]) != tok[1:]: - raise MatchError - var[pos] = query[n] - elif tok[0] == "^": - if not re.compile(tok[1:]).match(lower(query[n])): - raise MatchError - var[pos] = query[n] - elif tok[0] == "|": - n = self._matchmany(var, pos, n, query, pattern[i+1:], tok) - 1 - n = n + 1 - else: - if tok == "&": - pass - elif tok[0] == "&": - if not re.compile(tok[1:]).match(lower(query[n])): - raise MatchError - elif tok == "%": - if not self.forme: - raise MatchError - n = n - 1 - elif tok[0] == "/": - if not lower(self.server.user.nick)+tok[1:] == query[n]: - raise MatchError - elif tok == ".": - if 0 in map(lambda x: x == ".", query[n]): - raise MatchError - elif tok == "!": - if 0 in map(lambda x: x == "!", query[n]): - raise MatchError - elif tok == "?": - if "?" not in query[n] or 0 in map(lambda x: x in ["!","?"], query[n]): - raise MatchError - elif tok[0] == "\\": - if lower(query[n]) != tok[1:]: - raise MatchError - elif lower(query[n]) != tok: - raise MatchError - n = n + 1 - i = i + 1 - return n - - def _matchany(self, var, n, query, pattern): - l = len(query) - lp = len(pattern) - i = 0 - while i < lp: - tok = pattern[i] - if type(tok) == TupleType: - try: - return self._match(var, n, query, tok) - except MatchError: pass - elif type(tok) == ListType: - try: - return self._matchany(var, n, query, tok) - except MatchError: pass - elif tok == None: - return n - elif n >= l: - pass - elif type(tok) == IntType: - pos = tok - i = i+1 - tok = pattern[i] - if tok == "~": - var[pos] = query[n] - return n + 1 - elif tok[0] == "~": - if lower(query[n]) == tok[1:]: - var[pos] = query[n] - return n + 1 - elif tok[0] == "^": - if re.compile(tok[1:]).match(lower(query[n])): - var[pos] = query[n] - return n + 1 - elif tok[0] == "|": - try: - n = self._matchmany(var, pos, n, query, pattern[i+1:], tok) - return n - except MatchError: pass - else: - if tok == "&": - return n + 1 - elif tok[0] == "&": - if re.compile(tok[1:]).match(lower(query[n])): - return n + 1 - elif tok == "%": - if self.forme: - return n - elif tok[0] == "/": - if lower(self.server.user.nick)+tok[1:] == lower(query[n]): - return n + 1 - elif tok == ".": - if 0 not in map(lambda x: x == ".", query[n]): - return n + 1 - elif tok == "!": - if 0 not in map(lambda x: x == "!", query[n]): - return n + 1 - elif tok == "?": - if "?" in query[n] and 0 not in map(lambda x: x in ["!","?"], query[n]): - return n + 1 - elif tok[0] == "\\": - if lower(query[n]) == tok[1:]: - return n + 1 - elif lower(query[n]) == tok: - return n + 1 - i = i + 1 - raise MatchError - - def _matchmany(self, var, pos, n, query, pattern, str): - l = len(query) - a = 0 - b = 0 - ab = split(str[1:-1],",") - if len(ab) == 1: - try: - a = b = int(ab[0]) - b = b+n+1 - except ValueError: pass - elif len(ab) == 2: - try: a = int(ab[0]) - except ValueError: pass - try: - b = int(ab[1]) - b = b+n+1 - except ValueError: pass - a = a+n - if a > l: - raise MatchError - if b > l: - b = 0 - if str[-1] == "<": - if b == 0: b = l+1 - else: b = b+1 - step = 1 - else: - if b == 0: b = l+1 - step = -1 - a, b = b-1, a-1 - for i in range(a,b,step): - try: - self._match(var, i, query, pattern) - var[pos] = query[n:i] - return i - except MatchError: pass - raise MatchError - # vim:ts=4:sw=4:et --- 137,139 ---- Index: hook.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/hook.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** hook.py 4 Dec 2001 00:57:38 -0000 1.2 --- hook.py 12 May 2003 20:42:20 -0000 1.3 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. Index: main.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/main.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** main.py 9 May 2003 20:18:36 -0000 1.4 --- main.py 12 May 2003 20:42:20 -0000 1.5 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. Index: misc.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/misc.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** misc.py 9 May 2003 15:27:44 -0000 1.3 --- misc.py 12 May 2003 20:42:20 -0000 1.4 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. Index: module.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/module.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** module.py 5 May 2003 20:47:20 -0000 1.4 --- module.py 12 May 2003 20:42:20 -0000 1.5 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 22,29 **** class Modules: def __init__(self): ! self.__modules = {} def isloaded(self, name): ! return self.__modules.has_key(name) def loadlist(self, names): --- 22,32 ---- class Modules: def __init__(self): ! self._modules = {} def isloaded(self, name): ! return self._modules.has_key(name) ! ! def getlist(self): ! return self._modules.keys() def loadlist(self, names): *************** *** 55,63 **** for name, module, func, level in modulelist: try: ! func(self) except: traceback.print_exc() else: ! self.__modules[name] = module ret.append(name) return ret --- 58,66 ---- for name, module, func, level in modulelist: try: ! func() except: traceback.print_exc() else: ! self._modules[name] = module ret.append(name) return ret *************** *** 69,74 **** module = getattr(module, name) reload(module) ! getattr(module, "__loadmodule__")(self) ! self.__modules[name] = module return 1 except: --- 72,77 ---- module = getattr(module, name) reload(module) ! getattr(module, "__loadmodule__")() ! self._modules[name] = module return 1 except: *************** *** 76,84 **** def unload(self, name): ! module = self.__modules.get(name) if module: try: ! getattr(module, "__unloadmodule__")(self) ! del self.__modules[name] del sys.modules["pybot.modules."+name] return 1 --- 79,87 ---- def unload(self, name): ! module = self._modules.get(name) if module: try: ! getattr(module, "__unloadmodule__")() ! del self._modules[name] del sys.modules["pybot.modules."+name] return 1 *************** *** 87,91 **** def reload(self, name): ! module = self.__modules.get(name) if module: if self.unload(name): --- 90,94 ---- def reload(self, name): ! module = self._modules.get(name) if module: if self.unload(name): *************** *** 93,96 **** --- 96,108 ---- + class ModuleMethod: + def __init__(self, method): + self._method = method + + def __call__(self, *args, **kwargs): + if "defret" in kwargs: + del kwargs["defret"] + return self._method(*args, **kwargs) + class ModuleMethods: """Intermodule communication class. *************** *** 101,136 **** """ def __init__(self): ! self.__methods = {} ! def __return_defret(self, defret, *other): ! """Return the first parameter provided. ! ! This is the dummy method used when a named method that nobody is ! registered for is called. ! """ ! return defret def __getattr__(self, name): ! return self.__methods.get(name) or self.__return_defret def register(self, name, method): ! self.__methods[name] = method def unregister(self, name): ! if self.__methods.has_key(name): ! del self.__methods[name] class RemoteMethods: def __init__(self): ! self.__func = {} def register(self, funcname, func): ! self.__func[funcname] = func def unregister(self, funcname): ! del self.__func[funcname] def get_methods(self): ! return self.__func # vim:ts=4:sw=4:et --- 113,148 ---- """ def __init__(self): ! self._methods = {} ! def _return_defret(self, *args, **kwargs): ! try: ! return kwargs["defret"] ! except KeyError: ! return None def __getattr__(self, name): ! return self._methods.get(name) or self._return_defret def register(self, name, method): ! self._methods[name] = ModuleMethod(method) def unregister(self, name): ! try: ! del self._methods[name] ! except KeyError: ! pass class RemoteMethods: def __init__(self): ! self._func = {} def register(self, funcname, func): ! self._func[funcname] = func def unregister(self, funcname): ! del self._func[funcname] def get_methods(self): ! return self._func # vim:ts=4:sw=4:et Index: option.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/option.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** option.py 4 Dec 2001 00:57:38 -0000 1.3 --- option.py 12 May 2003 20:42:20 -0000 1.4 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 17,75 **** # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! from time import time class Options: def __init__(self): ! self.__hard = {} ! self.__soft = {} ! def gethard(self, name, default): ! return self.__hard.setdefault(name, default) ! def sethard(self, name, value): ! self.__hard[name] = value ! def hashard(self, name): ! return self.__hard.has_key(name) ! def delhard(self, name): try: ! del self.__hard[name] except KeyError: pass ! def getharddict(self): ! return self.__hard ! def setharddict(self, dict): ! self.__hard = dict ! def getsoft(self, name, default, keepalive=None): ! """Return temporary option. ! You may define for how long the option will be considered ! valid trough the keepalive argument (in seconds). If keepalive ! is None (default), option will stay valid while pybot is up, or ! at least until you change the keepalive to something else.""" ! opt = self.__soft.get(name) ! if opt: ! if opt[0] is None or time() < opt[0]: ! if keepalive is None: ! opt[0] = None ! elif keepalive: ! opt[0] = time()+keepalive ! return opt[1] ! else: ! del self.__soft[name] ! if keepalive is None: ! self.__soft[name] = [None, default] ! else: ! self.__soft[name] = [time()+keepalive, default] ! return default ! def setsoft(self, name, value, keepalive): ! return self.getsoft(name, value, keepalive) ! ! def hassoft(self, name): ! return self.__soft.has_key(name) # vim:ts=4:sw=4:et --- 17,95 ---- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! import time class Options: def __init__(self): ! self._dict = {} ! def getdict(self): ! return self._dict ! def setdict(self, dict): ! self._dict = dict ! def get(self, name, default=None, keepalive=0, reboot=0): ! """ ! You may define for how long the option will be considered ! valid trough the keepalive argument (in seconds). If keepalive ! is 0 (default), option will stay valid while pybot is up, or ! at least until you change the keepalive to something else. If ! reboot is true, the option will be alive even if pybot reboots, ! or quits and returns later. ! """ ! curtime = time.time() ! if keepalive: ! keepalive += curtime ! opt = self._dict.get(name) ! if opt: ! if not opt[1] or curtime < opt[1]: ! if keepalive: ! opt[1] = keepalive ! return opt[0] ! else: ! del self._dict[name] ! self._dict[name] = [default, keepalive, reboot] ! return default ! def set(self, name, value, keepalive=None, reboot=None): ! oldvalue = self.get(name) ! newvalue = [value, keepalive, reboot] ! if oldvalue: ! if ListType == type(oldvalue[0]) == type(newvalue[0]): ! oldvalue[0][:] = newvalue[0] ! newvalue[0] = oldvalue[0] ! elif DictType == type(oldvalue[0]) == type(newvalue[0]): ! oldvalue[0].clear() ! oldvalue[0].update(newvalue[0]) ! newvalue[0] = oldvalue[0] ! if keepalive is None: ! newvalue[1] = oldvalue[1] ! if reboot is None: ! newvalue[2] = oldvalue[2] ! self._dict[name] = newvalue ! ! def remove(self, name): try: ! del self._dict[name] except KeyError: pass ! def keys(self): ! return self._dict.keys() ! def has_key(self, name): ! return self._dict.has_key(name) ! def __getitem__(self, name): ! return self.get(name) ! def __setitem__(self, name, value): ! self.set(name, value) ! ! def __delitem__(self, name): ! self.remove(name) ! ! def __contains__(self, name): ! return self.has_key(name) # vim:ts=4:sw=4:et Index: runner.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/runner.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** runner.py 9 May 2003 20:18:36 -0000 1.2 --- runner.py 12 May 2003 20:42:20 -0000 1.3 *************** *** 1,5 **** #!/usr/bin/python # ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,5 ---- #!/usr/bin/python # ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 84,89 **** pybot.hooks.register("ConnectionError", print_connection_error) pybot.hooks.register("ConnectingError", print_connecting_error) ! pybot.modls.load("options") ! pybot.modls.load("modulecontrol") ret = pybot.main.loop() sys.exit(ret) --- 84,91 ---- pybot.hooks.register("ConnectionError", print_connection_error) pybot.hooks.register("ConnectingError", print_connecting_error) ! ! # Load modules which are part of the basic infrastructure ! pybot.modls.loadlist(["help", "options", "timer", "modulecontrol", ! "permission", "pong", "servercontrol"]) ret = pybot.main.loop() sys.exit(ret) Index: server.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/server.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** server.py 9 May 2003 20:18:36 -0000 1.3 --- server.py 12 May 2003 20:42:20 -0000 1.4 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 35,40 **** self.servers = [] ! def add(self, servername): ! self.servers.append(Server(servername)) def add_console(self): --- 35,40 ---- self.servers = [] ! def add(self, host, servername=None): ! self.servers.append(Server(host, servername)) def add_console(self): *************** *** 55,60 **** class BaseServer: ! def __init__(self, servername): ! self.servername = servername self.killed = 0 self._inlines = [] --- 55,64 ---- class BaseServer: ! def __init__(self, host, servername=None): ! if not servername: ! self.servername = host ! else: ! self.servername = servername ! self.host = host self.killed = 0 self._inlines = [] *************** *** 64,68 **** pass ! def changeserver(self, servername): pass --- 68,72 ---- pass ! def changeserver(self, host, servername): pass *************** *** 92,99 **** class Server(BaseServer): ! def __init__(self, servername): ! BaseServer.__init__(self, servername) ! self.changeserver(servername) self._inbuffer = "" self._outlines = [] --- 96,103 ---- class Server(BaseServer): ! def __init__(self, host, servername=None): ! BaseServer.__init__(self, host, servername) ! self.changeserver(host, servername) self._inbuffer = "" self._outlines = [] *************** *** 180,186 **** self._disconnect() ! def changeserver(self, servername): ! self.servername = servername ! tokens = split(servername,":") self._host = tokens[0] if len(tokens) == 2: --- 184,192 ---- self._disconnect() ! def changeserver(self, host, servername=None): ! if not servername: ! self.servername = host ! self.host = host ! tokens = split(host,":") self._host = tokens[0] if len(tokens) == 2: *************** *** 303,307 **** def emptyline(self): ! pass def postloop(self): --- 309,313 ---- def emptyline(self): ! self.show_lines() def postloop(self): Index: sqlitedb.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/sqlitedb.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** sqlitedb.py 8 May 2003 19:11:34 -0000 1.2 --- sqlitedb.py 12 May 2003 20:42:20 -0000 1.3 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 19,22 **** --- 19,25 ---- import pybot import sqlite + import re + + FIELDS = re.compile(r"\((.*)\)") class SQLiteDB: *************** *** 24,33 **** self._path = pybot.config.get("sqlite", "path") self._conn = sqlite.connect(self._path) - self._conn.autocommit = 1 - self.error = sqlite.DatabaseError def cursor(self): return self._conn.cursor() # vim:ts=4:sw=4:et --- 27,95 ---- self._path = pybot.config.get("sqlite", "path") self._conn = sqlite.connect(self._path) self.error = sqlite.DatabaseError + self.autocommit(1) + self.table("dict", "name,value") + + def copy(self): + return SQLiteDB() def cursor(self): return self._conn.cursor() + + def commit(self): + return self._conn.commit() + + def autocommit(self, enable): + self._conn.autocommit = enable + + def table(self, name, fields): + """\ + Besides creating tables when they don't exist, this function + will ensure that the given table has the given fields in the + given order, and change the table if not. + """ + cursor = self.cursor() + # Check that the table exist. + cursor.execute("select * from sqlite_master " + "where type='table' and name=%s", name) + row = cursor.fetchone() + if not row: + # No, it doesn't exist yet. + cursor.execute("create table %s (%s)" % (name, fields)) + elif row.sql.find("(%s)" % fields) == -1: + # It exist, but is invalid. We'll have to fix it. + self.autocommit(0) + cursor.execute("create temporary table temp_table (%s)" % fields) + m = FIELDS.search(row.sql) + if not m: + raise ValueError, "invalid sql in table '%s'" % name + oldfields = [x.strip() for x in m.group(1).split(",")] + copyfields = ",".join([x for x in fields.split(",") + if x in oldfields]) + cursor.execute("insert into temp_table (%s) select %s from %s" + % (copyfields, copyfields, name)) + cursor.execute("drop table %s" % name) + cursor.execute("create table %s (%s)" % (name, fields)) + cursor.execute("insert into %s select %s from temp_table" + % (name, fields)) + cursor.execute("drop table temp_table") + self.commit() + self.autocommit(1) + + def __getitem__(self, name): + cursor = self.cursor() + cursor.execute("select value from dict where name=%s", name) + if not cursor.rowcount: + return None + return cursor.fetchone().value + + def __setitem__(self, name, value): + del self[name] + cursor = self.cursor() + cursor.execute("insert into dict values (%s,%s)", name, value) + + def __delitem__(self, name): + cursor = self.cursor() + cursor.execute("delete from dict where name=%s", name) # vim:ts=4:sw=4:et Index: user.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/user.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** user.py 19 Jun 2002 21:46:22 -0000 1.3 --- user.py 12 May 2003 20:42:20 -0000 1.4 *************** *** 1,3 **** ! # Copyright (c) 2000-2001 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. --- 1,3 ---- ! # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. *************** *** 20,28 **** class User: ! def __init__(self, nick="", username="", host=""): ! self.nick = nick ! self.username = username ! self.host = host ! self.string = nick+"!"+username+"@"+host def setstring(self, str): --- 20,31 ---- class User: ! def __init__(self, nick="", username="", host="", string=None): ! if string: ! self.setstring(string) ! else: ! self.nick = nick ! self.username = username ! self.host = host ! self.string = nick+"!"+username+"@"+host def setstring(self, str): *************** *** 60,63 **** --- 63,69 ---- username, host = tokens return self.match(nick, username, host) + + def matchuser(self, user): + return self.match(user.nick, user.username, user.host) # vim:ts=4:sw=4:et |
From: Gustavo N. <nie...@us...> - 2003-05-12 20:42:25
|
Update of /cvsroot/pybot/pybot/pybot/util In directory sc8-pr-cvs1:/tmp/cvs-serv6970/pybot/util Removed Files: SOAP.py Log Message: Major work on pybot!! * modules/*: All modules moved to the new re matching system. * command.py: Removed old matching system. * modules/*: Pickling replaced by sqlite in all places were persistence was needed. * modules/*: All modules have inline help. * modules/*: All modules have permission help. * modules/infopack.py: Infopacks have help now. * *: Many method names changed to a better alternative. * options.py: Removed soft/hard relation. Now there's a single dict that might resist to reboots, if necessary. Notice that no standard module uses it for persistent options, since they use sqlite. * modules/example.py: Introduced basic sample module. * modules/soap.py: Obsoleted. Use xmlrpc instead. * scripts/pybotmsg.py: Added a basic xmlrpc client. * runner.py: Included other modules in the "default load" ones. * *: Other changes I probably forgot. --- SOAP.py DELETED --- |