From montanaro at users.sourceforge.net Fri May 11 02:23:10 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Thu, 10 May 2007 17:23:10 -0700 Subject: [Spambayes-checkins] spambayes/spambayes mboxutils.py, 1.10, 1.11 storage.py, 1.62, 1.63 Message-ID: <20070511002313.97ACB1E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv27616/spambayes Modified Files: mboxutils.py storage.py Log Message: patch 1707808 from Dave Abrahams - tte patch for imap Index: mboxutils.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/mboxutils.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** mboxutils.py 27 Mar 2007 10:59:24 -0000 1.10 --- mboxutils.py 11 May 2007 00:23:08 -0000 1.11 *************** *** 66,69 **** --- 66,77 ---- f.close() + def full_messages(msgs): + """A generator that transforms each message by calling its + get_full_message() method. Used for IMAP messages since they don't really + have their content by default. + """ + for x in msgs: + yield x.get_full_message() + def _cat(seqs): for seq in seqs: *************** *** 99,102 **** --- 107,142 ---- return _cat(mboxes) + elif name.startswith(":"): + # IMAP mailbox name: + # :username:password at server:folder1,...folderN + # :username:password at server:port:folder1,...folderN + # :username:password at server:ALL + # :username:password at server:port:ALL + parts = re.compile( + ':(?P[^@:]+):(?P[^@]+)@(?P[^:]+(:[0-9]+)?):(?P[^:]+)' + ).match(name).groupdict() + + from scripts.sb_imapfilter import IMAPSession, IMAPFolder + from spambayes import Stats, message + from spambayes.Options import options + + session = IMAPSession(parts['server']) + session.login(parts['user'], parts['pwd']) + folder_list = session.folder_list() + + if name == "ALL": + names = folder_list + else: + names = parts['name'].split(',') + + message_db = message.Message().message_info_db + stats = Stats.Stats(options, message_db) + mboxes = [ IMAPFolder(n,session,stats) for n in names ] + + if len(mboxes) == 1: + return full_messages(mboxes[0]) + else: + return _cat([full_messages(x) for x in mboxes]) + if os.path.isdir(name): # XXX Bogus: use a Maildir if /cur is a subdirectory, else a MHMailbox Index: storage.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/storage.py,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** storage.py 4 Apr 2007 11:49:05 -0000 1.62 --- storage.py 11 May 2007 00:23:08 -0000 1.63 *************** *** 477,481 **** print >> sys.stderr, 'Loading state from',self.db_name,'database' ! self.db = psycopg.connect(self.db_name) c = self.cursor() --- 477,481 ---- print >> sys.stderr, 'Loading state from',self.db_name,'database' ! self.db = psycopg.connect('dbname=' + self.db_name) c = self.cursor() *************** *** 768,773 **** abort = ZODB.Transaction.get_transaction().abort from ZODB.POSException import ConflictError from ZODB.POSException import ReadOnlyError - from ZODB.POSException import TransactionFailedError assert self.closed == False, "Can't store a closed database" --- 768,776 ---- abort = ZODB.Transaction.get_transaction().abort from ZODB.POSException import ConflictError + try: + from ZODB.POSException import TransactionFailedError + except: + from ZODB.POSException import TransactionError as TransactionFailedError from ZODB.POSException import ReadOnlyError assert self.closed == False, "Can't store a closed database" From montanaro at users.sourceforge.net Fri May 11 02:23:10 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Thu, 10 May 2007 17:23:10 -0700 Subject: [Spambayes-checkins] spambayes/scripts sb_imapfilter.py,1.66,1.67 Message-ID: <20070511002314.13D3E1E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/scripts In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv27616/scripts Modified Files: sb_imapfilter.py Log Message: patch 1707808 from Dave Abrahams - tte patch for imap Index: sb_imapfilter.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/scripts/sb_imapfilter.py,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** sb_imapfilter.py 7 Apr 2006 02:36:40 -0000 1.66 --- sb_imapfilter.py 11 May 2007 00:23:08 -0000 1.67 *************** *** 177,181 **** timeout = 60 # seconds ! def __init__(self, server, port, debug=0, do_expunge=False): # There's a tricky situation where if use_ssl is False, but we # try to connect to a IMAP over SSL server, we will just hang --- 177,191 ---- timeout = 60 # seconds ! def __init__(self, server, debug=0, do_expunge = options["imap", "expunge"] ): ! ! if server.find(':') > -1: ! server, port = server.split(':', 1) ! port = int(port) ! else: ! if options["imap", "use_ssl"]: ! port = 993 ! else: ! port = 143 ! # There's a tricky situation where if use_ssl is False, but we # try to connect to a IMAP over SSL server, we will just hang *************** *** 386,389 **** --- 396,400 ---- RFC822_HEADER_RE = re.compile(r"(RFC822.HEADER) (\{[\d]+\})") UID_RE = re.compile(r"(UID) ([\d]+)") + UID_RE2 = re.compile(r" *(UID) ([\d]+)\)") FETCH_RESPONSE_RE = re.compile(r"([0-9]+) \(([" + \ re.escape(FLAG_CHARS) + r"\"\{\}\(\)\\ ]*)\)?") *************** *** 407,410 **** --- 418,424 ---- data = {} expected_literal = None + if self.UID_RE2.match(response[-1]): + response = response[:-1] + for part in response: # We ignore parentheses by themselves, for convenience. *************** *** 721,724 **** --- 735,739 ---- break else: + self.imap_server.print_log() raise BadIMAPResponseError("recent", "Cannot find saved message") *************** *** 1076,1079 **** --- 1091,1112 ---- + def servers(promptForPass = False): + """Returns a list containing a tuple (server,user,passwd) for each IMAP server in options. + + If promptForPass is True or at least on password is missing from options, + prompts the user for each server's password. + """ + + servers = options["imap", "server"] + usernames = options["imap", "username"] + pwds = options["imap", "password"] + + if promptForPass or len(pwds) < len(usernames): + pwds = [] + for u in usernames: + pwds.append(getpass("Enter password for %s:" % (u,))) + + return zip(servers,usernames,pwds) + def run(force_UI=False): try: *************** *** 1090,1095 **** promptForPass = False launchUI = False - servers = "" - usernames = "" for opt, arg in opts: --- 1123,1126 ---- *************** *** 1133,1164 **** print "Done." ! if options["imap", "server"]: ! servers = options["imap", "server"] ! usernames = options["imap", "username"] ! if not promptForPass: ! pwds = options["imap", "password"] ! else: ! pwds = None ! if not launchUI and not force_UI: ! print "You need to specify both a server and a username." ! sys.exit() ! ! if promptForPass: ! pwds = [] ! for i in xrange(len(usernames)): ! pwds.append(getpass("Enter password for %s:" % (usernames[i],))) ! ! servers_data = [] ! for server, username, password in zip(servers, usernames, pwds or []): ! if server.find(':') > -1: ! server, port = server.split(':', 1) ! port = int(port) ! else: ! if options["imap", "use_ssl"]: ! port = 993 ! else: ! port = 143 ! servers_data.append((server, port, username, password)) # Load stats manager. stats = Stats.Stats(options, message_db) --- 1164,1173 ---- print "Done." ! if not ( launchUI or force_UI or options["imap", "server"] ): ! print "You need to specify both a server and a username." ! sys.exit() + servers_data = servers(promptForPass) + # Load stats manager. stats = Stats.Stats(options, message_db) *************** *** 1180,1188 **** if sleepTime or not (doClassify or doTrain): imaps = [] ! for server, port, username, password in servers_data: if server == "": imaps.append(None) else: ! imaps.append(IMAPSession(server, port, imapDebug, doExpunge)) def close_db(): --- 1189,1197 ---- if sleepTime or not (doClassify or doTrain): imaps = [] ! for server, username, password in servers_data: if server == "": imaps.append(None) else: ! imaps.append(IMAPSession(server, imapDebug, doExpunge)) def close_db(): *************** *** 1201,1204 **** --- 1210,1214 ---- httpServer = UserInterfaceServer(options["html_ui", "port"]) + pwds = [ x[2] for x in servers_data ] httpServer.register(IMAPUserInterface(classifier, imaps, pwds, IMAPSession, stats=stats, *************** *** 1214,1219 **** if doClassify or doTrain: imaps = [] ! for server, port, username, password in servers_data: ! imaps.append(((server, port, imapDebug, doExpunge), username, password)) --- 1224,1229 ---- if doClassify or doTrain: imaps = [] ! for server, username, password in servers_data: ! imaps.append(((server, imapDebug, doExpunge), username, password)) *************** *** 1230,1235 **** options.set_restore_point() while True: ! for (server, port, imapDebug, doExpunge), username, password in imaps: ! imap = IMAPSession(server, port, imapDebug, doExpunge) if options["globals", "verbose"]: print "Account: %s:%s" % (imap.server, imap.port) --- 1240,1245 ---- options.set_restore_point() while True: ! for (server, imapDebug, doExpunge), username, password in imaps: ! imap = IMAPSession(server, imapDebug, doExpunge) if options["globals", "verbose"]: print "Account: %s:%s" % (imap.server, imap.port) From montanaro at users.sourceforge.net Fri May 11 02:23:10 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Thu, 10 May 2007 17:23:10 -0700 Subject: [Spambayes-checkins] spambayes/contrib tte.py,1.17,1.18 Message-ID: <20070511002314.42B621E4005@bag.python.org> Update of /cvsroot/spambayes/spambayes/contrib In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv27616/contrib Modified Files: tte.py Log Message: patch 1707808 from Dave Abrahams - tte patch for imap Index: tte.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/contrib/tte.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** tte.py 5 Aug 2006 12:48:09 -0000 1.17 --- tte.py 11 May 2007 00:23:07 -0000 1.18 *************** *** 29,32 **** --- 29,35 ---- reduce the amount of input) are retained. + -C - Cull all messages which aren't used as training input during any + run by marking them deleted. Only works with IMAP folders. + -o sect:opt:val - Set [sect, opt] in the options database to val. *************** *** 95,98 **** --- 98,102 ---- return iter(seq) + def train(store, hambox, spambox, maxmsgs, maxrounds, tdict, reverse, verbose, ratio): *************** *** 101,107 **** spam_cutoff = Options.options["Categorization", "spam_cutoff"] ! nspam, nham = ratio ! while round < maxrounds and (hmisses or smisses or round == 0): round += 1 if verbose: --- 105,133 ---- spam_cutoff = Options.options["Categorization", "spam_cutoff"] ! # list-ify ham and spam iterators immediately. We don't really want to ! # fetch the messages multiple times, and this is no worse than what happened ! # before when -R was passed. ! hambone_ = list(mboxutils.getmbox(hambox)) ! spamcan_ = list(mboxutils.getmbox(spambox)) ! if reverse: ! hambone_ = list(reversed(hambone_)) ! spamcan_ = list(reversed(spamcan_)) ! ! if ratio: ! rspam,rham = ratio ! else: ! rspam,rham = len(spamcan_),len(hambone_) ! ! # define some indexing constants ! ham = 0 ! spam = 1 ! name = ('ham','spam') ! misses = [0,0] ! ! misclassified = lambda is_spam, score: ( ! is_spam and score < spam_cutoff or not is_spam and score > ham_cutoff) ! ! while round < maxrounds and (misses[ham] or misses[spam] or round == 0): round += 1 if verbose: *************** *** 109,173 **** start = datetime.datetime.now() ! hambone = mboxutils.getmbox(hambox) ! spamcan = mboxutils.getmbox(spambox) ! if reverse: ! hambone = reversed(list(hambone)) ! spamcan = reversed(list(spamcan)) ! hmisses = smisses = nmsgs = 0 ! try: ! while not maxmsgs or nmsgs < maxmsgs: ! hams = [] ! for i in range(nham): ! try: ! hams.append(hambone.next()) ! except StopIteration: ! # no hams left so exit ! if not hams: ! raise ! # use what we've collected ! break ! spams = [] ! for i in range(nspam): ! try: ! spams.append(spamcan.next()) ! except StopIteration: ! # no spams left so exit ! if not spams: ! raise ! # use what we've collected ! break ! nmsgs += len(hams) + len(spams) ! sys.stdout.write("\r%5d" % nmsgs) ! sys.stdout.flush() ! for (ham, spam) in map(None, hams, spams): ! if ham is not None: ! score = store.spamprob(tokenize(ham)) ! selector = ham["message-id"] or ham["subject"] ! if score > ham_cutoff and selector is not None: ! if verbose: ! print >> sys.stderr, "miss ham: %.6f %s" % ( ! score, selector) ! hmisses += 1 ! tdict[ham["message-id"]] = True ! store.learn(tokenize(ham), False) ! if spam is not None: ! score = store.spamprob(tokenize(spam)) ! selector = (spam["message-id"] or ! spam["subject"]) ! if score < spam_cutoff and selector is not None: ! if verbose: ! print >> sys.stderr, "miss spam: %.6f %s" % ( ! score, selector) ! smisses += 1 ! tdict[spam["message-id"]] = True ! store.learn(tokenize(spam), True) ! except StopIteration: ! pass delta = datetime.datetime.now()-start --- 135,173 ---- start = datetime.datetime.now() ! hambone = iter(hambone_) ! spamcan = iter(spamcan_) ! i = [0,0] ! msgs_processed = 0 ! misses = [0,0] ! training_sets = [hambone, spamcan] ! while not maxmsgs or msgs_processed < maxmsgs: ! # should the next message come from hambone or spamcan? ! train_spam = i[ham] * rspam > i[spam] * rham ! try: ! train_msg = training_sets[train_spam].next() ! except StopIteration: ! break; ! i[train_spam] += 1 ! msgs_processed += 1 ! sys.stdout.write("\r%5d" % msgs_processed) ! sys.stdout.flush() ! tokens = list(tokenize(train_msg)) ! score = store.spamprob(tokens) ! selector = train_msg["message-id"] or train_msg["subject"] ! ! if misclassified(train_spam,score) and selector is not None: ! if verbose: ! print >> sys.stderr, "\tmiss %s: %.6f %s" % ( ! name[train_spam], score, selector) ! ! misses[train_spam] += 1 ! tdict[train_msg["message-id"]] = True ! store.learn(tokens, train_spam) delta = datetime.datetime.now()-start *************** *** 175,212 **** print "\rround: %2d, msgs: %4d, ham misses: %3d, spam misses: %3d, %.1fs" % \ ! (round, nmsgs, hmisses, smisses, seconds) # We count all untrained messages so the user knows what was skipped. # We also tag them for saving so we don't lose messages which might have # value in a future run ! nhamleft = 0 ! try: ! while True: ! msg = hambone.next() ! score = store.spamprob(tokenize(msg)) ! if score > ham_cutoff: ! tdict[msg["message-id"]] = True ! nhamleft += 1 ! except StopIteration: ! if nhamleft: print nhamleft, "untrained hams" ! ! nspamleft = 0 ! try: ! while True: ! msg = spamcan.next() ! score = store.spamprob(tokenize(msg)) ! if score < spam_cutoff: ! tdict[msg["message-id"]] = True ! nspamleft += 1 ! except StopIteration: ! if nspamleft: print nspamleft, "untrained spams" def main(args): try: ! opts, args = getopt.getopt(args, "hg:s:d:p:o:m:r:c:vR", ["help", "good=", "spam=", "database=", "pickle=", "verbose", "option=", "max=", "maxrounds=", ! "cullext=", "reverse", "ratio="]) except getopt.GetoptError, msg: usage(msg) --- 175,232 ---- print "\rround: %2d, msgs: %4d, ham misses: %3d, spam misses: %3d, %.1fs" % \ ! (round, msgs_processed, misses[0], misses[1], seconds) + training_sets = [hambone,spamcan] + # We count all untrained messages so the user knows what was skipped. # We also tag them for saving so we don't lose messages which might have # value in a future run ! for is_spam in ham,spam: ! nleft = 0 ! try: ! while True: ! msg = training_sets[is_spam].next() ! score = store.spamprob(tokenize(msg)) ! ! if misclassified(is_spam,score): ! tdict[msg["message-id"]] = True ! nleft += 1 ! ! except StopIteration: ! if nleft: print nleft, "untrained %ss" % name[is_spam] + def cull(mbox_name, cullext, designation, tdict): + print "writing new %s mbox..." % designation + n = m = 0 + if cullext: + culled_mbox = file(mbox_name + cullext, "w") + + for msg in mboxutils.getmbox(mbox_name): + m += 1 + if msg["message-id"] in tdict: + if cullext: + culled_mbox.write(str(msg)) + n += 1 + elif not cullext: + response = msg.imap_server.uid( + "STORE", msg.uid, "+FLAGS.SILENT", "(\\Deleted \\Seen)") + command = "set %s to be deleted and seen" % (msg.uid,) + msg.imap_server.check_response(command, response) + + sys.stdout.write("\r%5d of %5d" % (n, m)) + sys.stdout.flush() + + sys.stdout.write("\n") + + if cullext: + culled_mbox.close() + def main(args): try: ! opts, args = getopt.getopt(args, "hg:s:d:p:o:m:r:c:vRuC", ["help", "good=", "spam=", "database=", "pickle=", "verbose", "option=", "max=", "maxrounds=", ! "cullext=", "reverse", "ratio=", "unbalanced"]) except getopt.GetoptError, msg: usage(msg) *************** *** 231,234 **** --- 251,256 ---- elif opt in ("-c", "--cullext"): cullext = arg + elif opt in ("-C", "--cullext"): + cullext = '' elif opt in ("-m", "--max"): maxmsgs = int(arg) *************** *** 237,240 **** --- 259,264 ---- elif opt in ("-R", "--reverse"): reverse = True + elif opt in ("-u", "--unbalanced"): + sh_ratio = None elif opt in ('-o', '--option'): Options.options.set_from_cmdline(arg, sys.stderr) *************** *** 260,291 **** sh_ratio) store.close() if cullext is not None: ! print "writing new ham mbox..." ! n = m = 0 ! newham = file(ham + cullext, "w") ! for msg in mboxutils.getmbox(ham): ! m += 1 ! if msg["message-id"] in tdict: ! newham.write(str(msg)) ! n += 1 ! sys.stdout.write("\r%5d of %5d" % (n, m)) ! sys.stdout.flush() ! sys.stdout.write("\n") ! newham.close() ! ! print "writing new spam mbox..." ! n = m = 0 ! newspam = file(spam + cullext, "w") ! for msg in mboxutils.getmbox(spam): ! m += 1 ! if msg["message-id"] in tdict: ! newspam.write(str(msg)) ! n += 1 ! sys.stdout.write("\r%5d of %5d" % (n, m)) ! sys.stdout.flush() ! sys.stdout.write("\n") ! newspam.close() return 0 --- 284,293 ---- sh_ratio) + store.store() store.close() if cullext is not None: ! cull(ham, cullext, 'ham', tdict) ! cull(spam, cullext, 'spam', tdict) return 0 From montanaro at users.sourceforge.net Fri May 11 04:24:57 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Thu, 10 May 2007 19:24:57 -0700 Subject: [Spambayes-checkins] spambayes/contrib tte.py,1.18,1.19 Message-ID: <20070511022500.70C171E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/contrib In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv13771 Modified Files: tte.py Log Message: --cullext can't be used to mean two different things. Index: tte.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/contrib/tte.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** tte.py 11 May 2007 00:23:07 -0000 1.18 --- tte.py 11 May 2007 02:24:54 -0000 1.19 *************** *** 228,232 **** "database=", "pickle=", "verbose", "option=", "max=", "maxrounds=", ! "cullext=", "reverse", "ratio=", "unbalanced"]) except getopt.GetoptError, msg: usage(msg) --- 228,233 ---- "database=", "pickle=", "verbose", "option=", "max=", "maxrounds=", ! "cullext=", "cull", "reverse", ! "ratio=", "unbalanced"]) except getopt.GetoptError, msg: usage(msg) *************** *** 251,255 **** elif opt in ("-c", "--cullext"): cullext = arg ! elif opt in ("-C", "--cullext"): cullext = '' elif opt in ("-m", "--max"): --- 252,256 ---- elif opt in ("-c", "--cullext"): cullext = arg ! elif opt in ("-C", "--cull"): cullext = '' elif opt in ("-m", "--max"): From montanaro at users.sourceforge.net Sun May 13 15:44:54 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Sun, 13 May 2007 06:44:54 -0700 Subject: [Spambayes-checkins] website faq.txt,1.92,1.93 Message-ID: <20070513134457.5CFAF1E4006@bag.python.org> Update of /cvsroot/spambayes/website In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv31143 Modified Files: faq.txt Log Message: Note about running on Vista. Index: faq.txt =================================================================== RCS file: /cvsroot/spambayes/website/faq.txt,v retrieving revision 1.92 retrieving revision 1.93 diff -C2 -d -r1.92 -r1.93 *** faq.txt 21 Dec 2006 01:36:21 -0000 1.92 --- faq.txt 13 May 2007 13:44:51 -0000 1.93 *************** *** 282,285 **** --- 282,296 ---- ============= + Does SpamBayes work on Windows Vista? + ------------------------------------- + + SpamBayes does work on Vista, though you will have to tweak the permissions + on: + + c:\\program files\\spambayes + + More details are available here: + + http://mail.python.org/pipermail/spambayes-bugs/2007-January/004119.html Does SpamBayes work with Outlook Express? From montanaro at users.sourceforge.net Wed May 16 02:02:47 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Tue, 15 May 2007 17:02:47 -0700 Subject: [Spambayes-checkins] spambayes/spambayes hammie.py,1.16,1.17 Message-ID: <20070516000252.072421E4002@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv21792 Modified Files: hammie.py Log Message: Why was this missing? Index: hammie.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/hammie.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** hammie.py 26 Jun 2004 01:57:38 -0000 1.16 --- hammie.py 16 May 2007 00:02:44 -0000 1.17 *************** *** 266,269 **** --- 266,271 ---- self.bayes.store() + def close(self): + self.store() def open(filename, useDB="dbm", mode='r'): From montanaro at users.sourceforge.net Fri May 18 05:54:41 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Thu, 17 May 2007 20:54:41 -0700 Subject: [Spambayes-checkins] spambayes setup.py,1.32,1.32.2.1 Message-ID: <20070518035447.62F0A1E4002@bag.python.org> Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv26612 Modified Files: Tag: CORESVR setup.py Log Message: Definitely not yet ready for prime time, but need to check this in so I have something to fall back on. Index: setup.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/setup.py,v retrieving revision 1.32 retrieving revision 1.32.2.1 diff -C2 -d -r1.32 -r1.32.2.1 *** setup.py 6 Dec 2004 03:04:17 -0000 1.32 --- setup.py 18 May 2007 03:54:39 -0000 1.32.2.1 *************** *** 100,103 **** --- 100,104 ---- 'scripts/sb_pop3dnd.py', 'scripts/sb_server.py', + 'scripts/core_server.py', 'scripts/sb_unheader.py', 'scripts/sb_upload.py', From montanaro at users.sourceforge.net Fri May 18 05:54:41 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Thu, 17 May 2007 20:54:41 -0700 Subject: [Spambayes-checkins] spambayes/spambayes CoreUI.py, NONE, 1.1.2.1 Options.py, 1.141, 1.141.2.1 Message-ID: <20070518035447.92A011E4004@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv26612/spambayes Modified Files: Tag: CORESVR Options.py Added Files: Tag: CORESVR CoreUI.py Log Message: Definitely not yet ready for prime time, but need to check this in so I have something to fall back on. --- NEW FILE: CoreUI.py --- """Core Web Interface Classes: CoreUserInterface - Interface class for basic (non-plugin) display Abstract: This module implements a browser based Spambayes user interface for the the core server. Users may use it to interface with various plugins. The following functions are currently included: [From the base class UserInterface] onClassify - classify a given message onWordquery - query a word from the database onTrain - train a message or mbox onSave - save the database and possibly shutdown [Here] onHome - a home page with various options onUpload - upload a message for later training (used by proxytee.py) [...1030 lines suppressed...] if details[0] != winerror.ERROR_ACCESS_DENIED: raise raise AlreadyRunningException # mutex opened - now check if we actually created it. if win32api.GetLastError()==winerror.ERROR_ALREADY_EXISTS: win32api.CloseHandle(hmutex) raise AlreadyRunningException self.mutex = hmutex return except ImportError: # no win32all - no worries, just start pass self.mutex = None def close_platform_mutex(self): """Toss out the current mutex.""" if sys.platform.startswith("win"): if self.mutex is not None: self.mutex.Close() self.mutex = None Index: Options.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Options.py,v retrieving revision 1.141 retrieving revision 1.141.2.1 diff -C2 -d -r1.141 -r1.141.2.1 *** Options.py 26 Mar 2007 07:57:13 -0000 1.141 --- Options.py 18 May 2007 03:54:39 -0000 1.141.2.1 *************** *** 653,656 **** --- 653,671 ---- PATH, DO_NOT_RESTORE), + ("core_spam_cache", _("Spam cache directory"), "core-spam-cache", + _("""Directory that SpamBayes should cache spam in. If this does + not exist, it will be created."""), + PATH, DO_NOT_RESTORE), + + ("core_ham_cache", _("Ham cache directory"), "core-ham-cache", + _("""Directory that SpamBayes should cache ham in. If this does + not exist, it will be created."""), + PATH, DO_NOT_RESTORE), + + ("core_unknown_cache", _("Unknown cache directory"), "core-unknown-cache", + _("""Directory that SpamBayes should cache unclassified messages in. + If this does not exist, it will be created."""), + PATH, DO_NOT_RESTORE), + ("cache_messages", _("Cache messages"), True, _("""You can disable the pop3proxy caching of messages. This From montanaro at users.sourceforge.net Fri May 18 05:54:41 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Thu, 17 May 2007 20:54:41 -0700 Subject: [Spambayes-checkins] spambayes/scripts core_server.py, NONE, 1.1.2.1 Message-ID: <20070518035447.C45A91E4002@bag.python.org> Update of /cvsroot/spambayes/spambayes/scripts In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv26612/scripts Added Files: Tag: CORESVR core_server.py Log Message: Definitely not yet ready for prime time, but need to check this in so I have something to fall back on. --- NEW FILE: core_server.py --- #!/usr/bin/env python """The primary server for SpamBayes. Currently serves the web interface only. Plugging in listeners for various protocols is TBD. This is a first cut at creating a standalone server which uses a plugin architecture to support different protocols. The primary motivation is that web apps like MoinMoin, Trac and Roundup can use spam detection, but they don't necessarily provide the mechanisms necessary to save ham and spam databases for retraining. By providing protocol plugins you should be able to fairly easily provide (for example) an XML-RPC interface web apps can use. The core server takes care of all the training bells and whistles. Usage: core_server.py [options] options: -h : Displays this help message. -d FILE : use the named DBM database file -p FILE : the the named Pickle database file -u port : User interface listens on this port number (default 8880; Browse http://localhost:8880/) -b : Launch a web browser showing the user interface. -o section:option:value : set [section, option] in the options database to value All command line arguments and switches take their default values from the [html_ui] section of bayescustomize.ini. """ # This module is part of the spambayes project, which is Copyright 2002 # The Python Software Foundation and is covered by the Python Software # Foundation license. __author__ = "Richie Hindle " __credits__ = "Tim Peters, Neale Pickett, Tim Stone, all the Spambayes folk." try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 try: reversed except NameError: # Maintain compatibility with Python 2.2 and 2.3 def reversed(seq): """for backwards compatibility w/ pre-2.4""" seq = list(seq[:]) seq.reverse() return iter(seq) _TODO = """ Protocol plugin interface: o POP3 o NNTP o Classifier for web apps (e.g. Trac, Roundup, Moin) Web training interface: User interface improvements: o Once the pieces are on separate pages, make the paste box bigger. o Deployment: Windows executable? atlaxwin and ctypes? Or just webbrowser? o "Reload database" button. New features: o Online manual. o Links to project homepage, mailing list, etc. o List of words with stats (it would have to be paged!) a la SpamSieve. Info: o Slightly-wordy index page; intro paragraph for each page. o In both stats and training results, report nham and nspam. o "Links" section (on homepage?) to project homepage, mailing list, etc. Gimmicks: o Graphs. Of something. Who cares what? """ import sys, getopt, time from email.Header import Header from spambayes import Dibbler from spambayes import storage from spambayes.Options import options, _ from spambayes.UserInterface import UserInterfaceServer from spambayes.Version import get_current_version from spambayes.CoreUI import CoreUserInterface, CoreState, \ AlreadyRunningException # Increase the stack size on MacOS X. Stolen from Lib/test/regrtest.py if sys.platform == 'darwin': try: import resource except ImportError: pass else: soft, hard = resource.getrlimit(resource.RLIMIT_STACK) newsoft = min(hard, max(soft, 1024*2048)) resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard)) # Option-parsing helper functions def _addressAndPort(s): """Decode a string representing a port to bind to, with optional address.""" s = s.strip() if ':' in s: addr, port = s.split(':') return addr, int(port) else: return '', int(s) def _addressPortStr((addr, port)): """Encode a string representing a port to bind to, with optional address.""" if not addr: return str(port) else: return '%s:%d' % (addr, port) def main(state): """Runs the proxy forever or until a 'KILL' command is received or someone hits Ctrl+Break.""" http_server = UserInterfaceServer(state.ui_port) http_server.register(CoreUserInterface(state)) Dibbler.run(launchBrowser=state.launch_ui) # =================================================================== # __main__ driver. # =================================================================== def run(): # Read the arguments. try: opts, args = getopt.getopt(sys.argv[1:], 'hbd:p:l:u:o:') except getopt.error, msg: print >> sys.stderr, str(msg) + '\n\n' + __doc__ sys.exit() state = CoreState() for opt, arg in opts: if opt == '-h': print >> sys.stderr, __doc__ sys.exit() elif opt == '-b': state.launch_ui = True # '-p' and '-d' are handled by the storage.database_type call # below, in case you are wondering why they are missing. elif opt == '-l': state.proxyPorts = [_addressAndPort(a) for a in arg.split(',')] elif opt == '-u': state.ui_port = int(arg) elif opt == '-o': options.set_from_cmdline(arg, sys.stderr) state.db_name, state.use_db = storage.database_type(opts) # Let the user know what they are using... v = get_current_version() print "%s\n" % (v.get_long_version("SpamBayes Core Proxy"),) if 0 <= len(args) <= 2: # Normal usage, with optional server name and port number. if len(args) == 1: state.servers = [(args[0], 110)] elif len(args) == 2: state.servers = [(args[0], int(args[1]))] try: state.prepare() except AlreadyRunningException: print >> sys.stderr, \ "ERROR: The proxy is already running on this machine." print >> sys.stderr, "Please stop the existing proxy and try again" return # kick everything off try: main(state) finally: state.close() else: print >> sys.stderr, __doc__ if __name__ == '__main__': run() From montanaro at users.sourceforge.net Mon May 21 14:25:28 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Mon, 21 May 2007 05:25:28 -0700 Subject: [Spambayes-checkins] spambayes/spambayes CoreUI.py, 1.1.2.1, 1.1.2.2 Message-ID: <20070521122534.8FDC31E4005@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv14093 Modified Files: Tag: CORESVR CoreUI.py Log Message: Damn... Thwarted in my attempt to move toward PEP8. Index: CoreUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Attic/CoreUI.py,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** CoreUI.py 18 May 2007 03:54:39 -0000 1.1.2.1 --- CoreUI.py 21 May 2007 12:25:26 -0000 1.1.2.2 *************** *** 855,859 **** spambayes.message.Message.message_info_db = None ! self.spam_corpus = self.ham_corpus = self.unknown_corpus = None self.spam_trainer = self.ham_trainer = None --- 855,859 ---- spambayes.message.Message.message_info_db = None ! self.spamCorpus = self.hamCorpus = self.unknownCorpus = None self.spam_trainer = self.ham_trainer = None *************** *** 953,963 **** factory = FileMessageFactory() age = options["Storage", "cache_expiry_days"]*24*60*60 ! self.spam_corpus = ExpiryFileCorpus(age, factory, sc, '[0123456789\-]*', cacheSize=20) ! self.ham_corpus = ExpiryFileCorpus(age, factory, hc, '[0123456789\-]*', cacheSize=20) ! self.unknown_corpus = ExpiryFileCorpus(age, factory, uc, '[0123456789\-]*', cacheSize=20) --- 953,963 ---- factory = FileMessageFactory() age = options["Storage", "cache_expiry_days"]*24*60*60 ! self.spamCorpus = ExpiryFileCorpus(age, factory, sc, '[0123456789\-]*', cacheSize=20) ! self.hamCorpus = ExpiryFileCorpus(age, factory, hc, '[0123456789\-]*', cacheSize=20) ! self.unknownCorpus = ExpiryFileCorpus(age, factory, uc, '[0123456789\-]*', cacheSize=20) *************** *** 968,980 **** # messages from not only the trained corpora, but the unknown # as well. ! self.spam_corpus.removeExpiredMessages() ! self.ham_corpus.removeExpiredMessages() ! self.unknown_corpus.removeExpiredMessages() # Create the Trainers. self.spam_trainer = storage.SpamTrainer(self.bayes) self.ham_trainer = storage.HamTrainer(self.bayes) ! self.spam_corpus.addObserver(self.spam_trainer) ! self.ham_corpus.addObserver(self.ham_trainer) def get_new_message_name(self): --- 968,980 ---- # messages from not only the trained corpora, but the unknown # as well. ! self.spamCorpus.removeExpiredMessages() ! self.hamCorpus.removeExpiredMessages() ! self.unknownCorpus.removeExpiredMessages() # Create the Trainers. self.spam_trainer = storage.SpamTrainer(self.bayes) self.ham_trainer = storage.HamTrainer(self.bayes) ! self.spamCorpus.addObserver(self.spam_trainer) ! self.hamCorpus.addObserver(self.ham_trainer) def get_new_message_name(self): From montanaro at users.sourceforge.net Tue May 22 04:00:31 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Mon, 21 May 2007 19:00:31 -0700 Subject: [Spambayes-checkins] spambayes/spambayes storage.py,1.63,1.63.2.1 Message-ID: <20070522020036.2E4EA1E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv27760 Modified Files: Tag: CORESVR storage.py Log Message: Delete explicit test against False. Index: storage.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/storage.py,v retrieving revision 1.63 retrieving revision 1.63.2.1 diff -C2 -d -r1.63 -r1.63.2.1 *** storage.py 11 May 2007 00:23:08 -0000 1.63 --- storage.py 22 May 2007 02:00:22 -0000 1.63.2.1 *************** *** 774,778 **** from ZODB.POSException import ReadOnlyError ! assert self.closed == False, "Can't store a closed database" if options["globals", "verbose"]: --- 774,778 ---- from ZODB.POSException import ReadOnlyError ! assert not self.closed, "Can't store a closed database" if options["globals", "verbose"]: From montanaro at users.sourceforge.net Tue May 22 04:27:13 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Mon, 21 May 2007 19:27:13 -0700 Subject: [Spambayes-checkins] spambayes/spambayes storage.py, 1.63.2.1, 1.63.2.2 Message-ID: <20070522022719.509B51E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv6593 Modified Files: Tag: CORESVR storage.py Log Message: Note what file was unavailable to use for FileStorage. Index: storage.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/storage.py,v retrieving revision 1.63.2.1 retrieving revision 1.63.2.2 diff -C2 -d -r1.63.2.1 -r1.63.2.2 *** storage.py 22 May 2007 02:00:22 -0000 1.63.2.1 --- storage.py 22 May 2007 02:27:09 -0000 1.63.2.2 *************** *** 721,726 **** import ZODB from ZODB.FileStorage import FileStorage ! self.storage = FileStorage(self.db_filename, ! read_only=self.mode=='r') def load(self): --- 721,731 ---- import ZODB from ZODB.FileStorage import FileStorage ! try: ! self.storage = FileStorage(self.db_filename, ! read_only=self.mode=='r') ! except IOError, msg: ! print >> sys.stderr, ("Could not create FileStorage from", ! self.db_filename) ! raise def load(self): From montanaro at users.sourceforge.net Tue May 22 05:01:49 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Mon, 21 May 2007 20:01:49 -0700 Subject: [Spambayes-checkins] spambayes/spambayes/core_resources - New directory Message-ID: <20070522030155.43DCB1E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes/core_resources In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv19050/core_resources Log Message: Directory /cvsroot/spambayes/spambayes/spambayes/core_resources added to the repository --> Using per-directory sticky tag `CORESVR' From montanaro at users.sourceforge.net Tue May 22 05:05:14 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Mon, 21 May 2007 20:05:14 -0700 Subject: [Spambayes-checkins] spambayes/spambayes CoreUI.py, 1.1.2.2, 1.1.2.3 Message-ID: <20070522030517.7A6621E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv20756 Modified Files: Tag: CORESVR CoreUI.py Log Message: More PEP-8 reversions. Try to clean up the message info db stuff a little. Enough for tonight. My head is swimming... Index: CoreUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Attic/CoreUI.py,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** CoreUI.py 21 May 2007 12:25:26 -0000 1.1.2.2 --- CoreUI.py 22 May 2007 03:05:12 -0000 1.1.2.3 *************** *** 779,782 **** --- 779,796 ---- return errmsg + def readUIResources(self): + """Returns ui.html and a dictionary of Gifs.""" + if self.lang_manager: + ui_html = self.lang_manager.import_ui_html() + else: + from spambayes.core_resources import ui_html + images = {} + for baseName in UserInterface.IMAGES: + moduleName = '%s.%s_gif' % ('spambayes.core_resources', baseName) + module = __import__(moduleName, {}, {}, ('spambayes', + 'core_resources')) + images[baseName] = module.data + return ui_html.data, images + class CoreState: """This keeps the global state of the module - the command-line options, *************** *** 794,812 **** self.prepared = False self.can_stop = True - self.mdb = None ! # Unique names for cached messages - see `get_new_message_name()` below. self.last_base_message_name = '' self.uniquifier = 2 # Set up the statistics. ! self.num_spams = 0 ! self.num_hams = 0 ! self.num_unsure = 0 self.servers = "" - self.init() - # Load up the other settings from Option.py / bayescustomize.ini self.ui_port = options["html_ui", "port"] --- 808,823 ---- self.prepared = False self.can_stop = True ! # Unique names for cached messages - see `getNewMessageName()` below. self.last_base_message_name = '' self.uniquifier = 2 # Set up the statistics. ! self.numSpams = 0 ! self.numHams = 0 ! self.numUnsure = 0 self.servers = "" # Load up the other settings from Option.py / bayescustomize.ini self.ui_port = options["html_ui", "port"] *************** *** 816,836 **** self.is_test = False def init(self): assert not self.prepared, "init after prepare, but before close" ! # Load the environment for translation. ! self.lang_manager = i18n.LanguageManager() ! # Set the system user default language. ! self.lang_manager.set_language(\ ! self.lang_manager.locale_default_lang()) ! # Set interface to use the user language in the configuration file. ! for language in reversed(options["globals", "language"]): ! # We leave the default in there as the last option, to fall ! # back on if necessary. ! self.lang_manager.add_language(language) ! if options["globals", "verbose"]: ! print "Asked to add languages: " + \ ! ", ".join(options["globals", "language"]) ! print "Set language to " + \ ! str(self.lang_manager.current_langs_codes) # Open the log file. --- 827,851 ---- self.is_test = False + self.init() + def init(self): assert not self.prepared, "init after prepare, but before close" ! ## no i18n yet... ! ## # Load the environment for translation. ! ## self.lang_manager = i18n.LanguageManager() ! ## # Set the system user default language. ! ## self.lang_manager.set_language(\ ! ## self.lang_manager.locale_default_lang()) ! ## # Set interface to use the user language in the configuration file. ! ## for language in reversed(options["globals", "language"]): ! ## # We leave the default in there as the last option, to fall ! ## # back on if necessary. ! ## self.lang_manager.add_language(language) ! ## if options["globals", "verbose"]: ! ## print "Asked to add languages: " + \ ! ## ", ".join(options["globals", "language"]) ! ## print "Set language to " + \ ! ## str(self.lang_manager.current_langs_codes) ! self.lang_manager = None # Open the log file. *************** *** 849,857 **** self.bayes.close() self.bayes = None ! if self.mdb is not None: ! self.mdb.store() ! self.mdb.close() ! self.mdb = None ! spambayes.message.Message.message_info_db = None self.spamCorpus = self.hamCorpus = self.unknownCorpus = None --- 864,868 ---- self.bayes.close() self.bayes = None ! spambayes.message.Message().message_info_db = None self.spamCorpus = self.hamCorpus = self.unknownCorpus = None *************** *** 931,938 **** self.db_name, self.use_db = storage.database_type([]) self.bayes = storage.open_storage(self.db_name, self.use_db) - self.mdb = spambayes.message.Message().message_info_db # Load stats manager. ! self.stats = Stats.Stats(options, self.mdb) self.build_status_strings() --- 942,949 ---- self.db_name, self.use_db = storage.database_type([]) self.bayes = storage.open_storage(self.db_name, self.use_db) # Load stats manager. ! self.stats = Stats.Stats(options, ! spambayes.message.Message().message_info_db) self.build_status_strings() *************** *** 978,982 **** self.hamCorpus.addObserver(self.ham_trainer) ! def get_new_message_name(self): """The message name is the time it arrived with a uniquifier appended if two arrive within one clock tick of each other. --- 989,993 ---- self.hamCorpus.addObserver(self.ham_trainer) ! def getNewMessageName(self): """The message name is the time it arrived with a uniquifier appended if two arrive within one clock tick of each other. *************** *** 1000,1008 **** """ if cls == options["Headers", "header_ham_string"]: ! self.num_hams += 1 elif cls == options["Headers", "header_spam_string"]: ! self.num_spams += 1 else: ! self.num_unsure += 1 self.stats.recordClassification(score) --- 1011,1019 ---- """ if cls == options["Headers", "header_ham_string"]: ! self.numHams += 1 elif cls == options["Headers", "header_spam_string"]: ! self.numSpams += 1 else: ! self.numUnsure += 1 self.stats.recordClassification(score) From montanaro at users.sourceforge.net Tue May 22 05:06:10 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Mon, 21 May 2007 20:06:10 -0700 Subject: [Spambayes-checkins] spambayes setup.py,1.32.2.1,1.32.2.2 Message-ID: <20070522030613.1C7781E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv21160 Modified Files: Tag: CORESVR setup.py Log Message: process core_resources subpackage Index: setup.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/setup.py,v retrieving revision 1.32.2.1 retrieving revision 1.32.2.2 diff -C2 -d -r1.32.2.1 -r1.32.2.2 *** setup.py 18 May 2007 03:54:39 -0000 1.32.2.1 --- setup.py 22 May 2007 03:06:07 -0000 1.32.2.2 *************** *** 129,132 **** --- 129,133 ---- 'spambayes', 'spambayes.resources', + 'spambayes.core_resources', ], classifiers = [ From montanaro at users.sourceforge.net Tue May 22 05:03:00 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Mon, 21 May 2007 20:03:00 -0700 Subject: [Spambayes-checkins] spambayes/spambayes/core_resources README.txt, NONE, 1.1.2.1 README_txt.py, NONE, 1.1.2.1 __init__.py, NONE, 1.1.2.1 classify.gif, NONE, 1.1.2.1 classify_gif.py, NONE, 1.1.2.1 config.gif, NONE, 1.1.2.1 config_gif.py, NONE, 1.1.2.1 helmet.gif, NONE, 1.1.2.1 helmet_gif.py, NONE, 1.1.2.1 help.gif, NONE, 1.1.2.1 help_gif.py, NONE, 1.1.2.1 message.gif, NONE, 1.1.2.1 message_gif.py, NONE, 1.1.2.1 query.gif, NONE, 1.1.2.1 query_gif.py, NONE, 1.1.2.1 scanning__init__.py, NONE, 1.1.2.1 status.gif, NONE, 1.1.2.1 status_gif.py, NONE, 1.1.2.1 train.gif, NONE, 1.1.2.1 train_gif.py, NONE, 1.1.2.1 ui.html, NONE, 1.1.2.1 ui.psp, NONE, 1.1.2.1 ui_html.py, NONE, 1.1.2.1 ui_psp.py, NONE, 1.1.2.1 Message-ID: <20070522033751.47F0B1E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes/core_resources In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv19508 Added Files: Tag: CORESVR README.txt README_txt.py __init__.py classify.gif classify_gif.py config.gif config_gif.py helmet.gif helmet_gif.py help.gif help_gif.py message.gif message_gif.py query.gif query_gif.py scanning__init__.py status.gif status_gif.py train.gif train_gif.py ui.html ui.psp ui_html.py ui_psp.py Log Message: isolate Core UI templates from pop3 proxy version --- NEW FILE: README.txt --- When running SpamBayes from source, you need to install resourcepackage from http://resourcepackage.sourceforge.net/ in order for your changes to anything in the "resource" directory to take effect. Download ResourcePackage-1.0.0.tar.gz, unpack it into a temporary area, cd to that area, and run "python setup.py install". You can then delete the unpacked files. --- NEW FILE: README_txt.py --- # -*- coding: ISO-8859-1 -*- """Resource README_txt (from file README.txt)""" # written by resourcepackage: (1, 0, 0) source = 'README.txt' package = 'spambayes.core_resources' import zlib data = zlib.decompress("x?]??N?0\014??>??sIaeD<\000?\0011Z??T?D?+T?\036??_P???|w?gf?n\"????????+\ \006-\013??i?\016{? ?\011V0?j4?P?????Fn?\017??>???Z?^CQ?\013[?\020\024M?p??+b&\031??JC?\ [>?x?eF{??H?r????????ap%\000??[?B?y??~??\037???\037#\015?O?M?P???? \030/?(9\ ???C always re-loads from external files, otherwise ## only reloads if the file is newer than the generated .py file. # force = 1, ) --- NEW FILE: classify.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: classify_gif.py --- # -*- coding: ISO-8859-1 -*- """Resource classify_gif (from file classify.gif)""" # written by resourcepackage: (1, 0, 0) source = 'classify.gif' package = 'spambayes.resources' data = "GIF89a(\000(\000?\000\000\000?\004??\010??\014??\020??\024??\030??\034?? ??$??(??,??0??4??8??\ ?\\??\001?\037\024]$??@\004?\023+\003<\030\021!??\004-\"????\001??>X?\000??\004\002\005:n`?\011 ?\017?=\036\000\010@?`J\ \003\034t\ ?\006?!\005???\027/\\\013\000?U 0\020?e?@???\002?p??;]+\000\0064\004Z???\000o\017:*?\005??3??\016\020??\001G\ V\004'??\003\012\011@?\003\010\004|??u\017??Q\000\022? \001a\001@@?\005\002?\024?D'??\034K.?V?F\034y\004?H$a???,??\ ??0?(??4?h??8????+\006\004\000;" ### end --- NEW FILE: config.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: config_gif.py --- # -*- coding: ISO-8859-1 -*- """Resource config_gif (from file config.gif)""" # written by resourcepackage: (1, 0, 0) source = 'config.gif' package = 'spambayes.resources' data = "GIF89a(\000(\000?\000\000\000?\004??\010??\014??\020??\024??\030??\034?? ??$??(??,??0??4??8??D?XP\006\013\0362b?\ ????I\032,|?\020?c?I?4N??a??\017\032/a??Q?f??4Z???????\020E\016U??G??\026K\"????R?\ =p\"???\002?\0141 z?1\024???R\011~??@?\002\007\026?\032?jsh?\023V{?H?\001?\005\005\006\006\0240? \002\012?\037bth??\ G?\017%????\"??\030\023\024\014?\\????)P`?\020?\004?\027??.?p?\007\017\014\013bC?,?\000???\0258p???\005???z\ ?\0219u\013\007\006\002o\036 ?6?\003?\017 always re-loads from external files, otherwise ## only reloads if the file is newer than the generated .py file. # force = 1, ) # ResourcePackage license added by Richie Hindle , # since this is "Redistribution and use in source form". Note that binary # Spambayes packages don't redistribute this file or rely on ResourcePackage; # it's only used at development time (and even developers don't need it # unless they want to change the resources). Kudos to Mike Fletcher for # ResourcePackage - excellent tool! __license__ = """ ResourcePackage License Copyright (c) 2003, Michael C. Fletcher, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. The name of Michael C. Fletcher, or the name of any Contributor, may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS NOT FAULT TOLERANT AND SHOULD NOT BE USED IN ANY SITUATION ENDANGERING HUMAN LIFE OR PROPERTY. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ --- NEW FILE: status.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: status_gif.py --- # -*- coding: ISO-8859-1 -*- """Resource status_gif (from file status.gif)""" # written by resourcepackage: (1, 0, 0) source = 'status.gif' package = 'spambayes.resources' data = "GIF89a(\000(\000?\000\000\000?\004??\010??\014??\020??\024??\030??\034?? ??$??(??,??0??4??8??`yd\007\012 SpamBayes Core Server User Interface

Introduction

This file, ui.html, defines the look-and-feel of the user interface of the SpamBayes Core Server. The various pieces of HTML defined here are extracted and manipulated at runtime to dynamically produce the HTML that the SpamBayes Server serves up - this file acts as a palette of HTML components. PyMeldLite is the module that provides the HTML-to-object mapping layer that makes all this possible. Each piece of HTML that needs to be manipulated has an id tag, and becomes a Python object at runtime.

This "Introduction" section serves as an introduction to this file. It does not require translation and is never used in the run-time interface.

As an example of how this works, here is an editbox with an id of examplebox: PyMeldLite lets you manipulate the HTML programmatically:

    >>> import PyMeldLite
    >>> html = open("ui.html", "rt").read()
    >>> doc = PyMeldLite.Container(html)
    >>> print doc.examplebox
    <input id="examplebox" size="10" type="text" value="example"/>
    >>> doc.examplebox.value = "Changed"
    >>> print doc.examplebox
    <input id="examplebox" size="10" type="text" value="Changed"/>
    

So the Python code to build the HTML user interface pages doesn't need to faff about pasting strings together, or building HTML components from scratch in code. And the look-and-feel is controlled solely by this one HTML file - changing the stylesheet, translating into other languages, adding a new piece of user interface - all of these things are very easy.

Below are all the user interface components along with their ids.


headedBox

Headed box
  This is a "headedBox". Most of the user interfaces pieces are presented in one of these. The pieces aren't presented in these boxes here in ui.html to avoid duplication of HTML. As such, this section does not need translation.
 

The help page

SpamBayes Help
  Sorry, there isn't any specific help available for that section.

If you believe you may have found a bug in SpamBayes, or are at a loss as to how you can proceed, you can ask the SpamBayes mailing list for assistance. Note that the members of this list are volunteers that answer questions in their free time, so an answer to your question might take a little while to appear. If you are quite certain that you have found a bug, then you're probably better off submitting this via the SourceForge tracking system, as sometimes things get lost on the list, particularly in busy times or when the latest virus is flooding the net with bogus messages.
 
There is certain information which people need to know in order to suggest how you might fix any problems. To help make sure that you have all this information, SpamBayes can create a help message for you. If you choose to email the list without using this, please ensure that you have all the pertinent information. (Otherwise your response is likely to be "please tell us ...").

Context-sensitive help page text

Review Page Help

When you first start using SpamBayes, all your mail will be classified as 'unsure' because SpamBayes doesn't have any preconceived ideas about what good or bad mail looks like. As soon as you start training the classification will improve, and by the time you've classified even 20 messages of each you'll be seeing quite reasonable results.

SpamBayes saves a temporary copy of all incoming mail so that classification can be independant of whatever mail client you are using. You need to run through these messages and tell SpamBayes how to handle mail like that in the future. This page lists messages that have arrived in the last %(cache_expiry_days)s days and that have not yet been trained. For each message listed, you need to choose to either discard (don't train on this message), defer (leave training on this message until later), or train (as either good - ham, or bad - spam). You do this by simply clicking in the circle in the appropriate column; if you wish to change all the messages to the same action, you can simply click the column heading.

You are presented with the subject and sender of each message, but, if this isn't enough information for you to make a decision on the message, you can also view the message text (this is the raw text, so you can't do any damage if the message contains a virus or any other malignant data). To do this, simply click on the subject of the message.

Once you have chosen the actions you wish to perform on all the displayed messages, click the Train button at the end of the page. SpamBayes will then update its database to reflect this data.

Note that the messages are split up into the classification that SpamBayes would place the message with current training data (if this is correct, you might choose to Discard the message, rather than train on it - see the SpamBayes wiki for discussion of training techniques). You can also see the Tokens that the message contains (the words in the message, plus some additional tokens that SpamBayes generates) and the Clues that SpamBayes used in classifying the message (not all tokens are used in classification).

So that the page isn't overwhelmingly long, messages waiting for review are split by the day they arrived. You can use the Previous Day or Next Day buttons at the top of the page to move between days. If mail arrives while the review page is open the new messages will not be automatically added to the displayed list; to add the new message, click the Refresh button at the top of the page.

Statistics Page Help

SpamBayes keeps track of certain information about the messages that are classified. For your interest, this page displays statistics about the messages that have been classified and trained so far.

Currently the page displays information about the number of messages that have been classified as good, bad and unsure, how many of these were false negatives or positives, and how many messages were classified as unsure (and what their correct classification was).

Note that the data for this page resides in the "message info" database that SpamBayes uses, and so only reflects messages since the last time this database was created.

Home Page Help

This is the main page for the SpamBayes web interface. You are presented with some information about the current status of SpamBayes, and can follow links to review messages or alter your configuration.

If you have messages stored in a mbox or dbx (Outlook Express) file that you wish to 'bulk' train, or if you wish to train on a message that you type in, you can do this on this page. Click the "Browse" button (or paste the text in, including headers), and then click the Train as Ham or Train as Spam button.

Likewise, if you have a message that you wish to classify, you can do this. Either paste the message into the text box, or click "Browse" and locate the text file that the message is located in. Click Classify, and you will be taken to a page describing the classification of that message.

If you want to find out information about a word in the statistics database that forms the heart of SpamBayes, you can use the "Word Query" facility. Enter in the word that you wish to search for and click Tell me about this word. If you enable the advanced find query, you can also search using wildcards or regular expressions.

You can also search for a specific message in the cache of temporary copies of messages that have been proxied. You might wish to do this if you realise that you have incorrectly trained a message and need to correct the training. You can search the subject, headers, or message body, or for the SpamBayes ID (which is in the headers of messages that SpamBayes proxies). Messages that are found will be presented in the standard review page. Note that once messages expire from the cache (after %(cache_expiry_days)s days), you can no longer find them.


A pre-filled-in 'help' message

Send Help Message
From:
Subject:
Message:
Attach Log file:

status

Messages classified this session: 0 spam, 0 ham, 0 unsure.
Total messages trained: Spam: 0 Ham: 0
More statistics...
          You can configure your SpamBayes
      system using the Configuration page.
Warning: please insert warning message here! The warnings are all dynamically inserted, and so translating this text is not necessary.

reviewText

The SpamBayes server stores all the messages it sees. You can train the classifier based on those messages using the Review messages page.


reviewTable

These are messages that you can use to train the classifier. Check the appropriate button for each message, then click 'Train' below. 'Defer' leaves the message here, to be trained on later. Click one of the Discard / Defer / Ham / Spam headers to check all of the buttons in that section in one go. Click one of the other headers to sort messages (within their classification) by that header (note that sorting will lose any changes you have made to the page).

          
 
Messages classified as TYPE:
Subject Received: Discard / Defer / Ham / Spam Score:
Richie Hindle <richie at entrian.com> Sat, 11 Sep 2003 19:03:11                  0.00% Clues | Tokens
   
    

upload

Either upload a message, mbox or dbx file:
Or paste one whole message (including headers) here:

(The upload form gets used for both training and classifying - the inappropriate pieces are removed at runtime.)


wordQuery


Basic Query
Wildcard Query
Regular Expression Query
Ignore Case
Maximum results

findMessage

Search in...
SpamBayes ID
Subject
Message headers
Message body
Ignore Case
Maximum results

wordStats

Number of spam messages: 123.
Number of ham messages: 456.
Probability that a message containing this word is spam: 0.789.
Word # Spam # Ham Probability
spambayes 123 436 .789

classifyResults

Spam probability: 0.123. Original probability: 0.125.

(The table of clues goes here, like this but in a headedBox):
Word Probability Times in ham Times in spam
Example word 0.123 1 2

Return Home or classify another:

(The Classify form goes here)

configForm

This page allows you to change the options that control how SpamBayes processes your messages. Your options are stored in /example/pathname.

Label      

(Help text goes here.)

Label
Value Label 
     

(Help text goes here.)

Current Value:  (value)
Current Value:  (value)
 
Folder name

(Help text goes here.)


shutdownMessage

Shutdown. Goodbye.


--- NEW FILE: ui.psp --- (This appears to be a binary file; contents omitted.) --- NEW FILE: ui_html.py --- # -*- coding: ISO-8859-1 -*- """Resource ui_html (from file ui.html)""" # written by resourcepackage: (1, 0, 0) source = 'ui.html' package = 'spambayes.core_resources' import zlib data = zlib.decompress("x??=ks?F???+&??!?R$%?N?\007om?Y???}???T*?\032\002C\022+\020@?\020????~?\014\006\017???\ ??:gW\"\001LOwO??\007:?????????\022W?o?????x??Rx??????????K??d8>\022??L??\ ??D????\037?????\\??K?\020~?Q\031+\021?\027\036}?&\0373?|!??\020?i??G???\\?T???I???\014??\ ?\036??KUJ?(??P?VEw\027??\014\026?\023A\012?&?????\001_\032?=??>?rU8\003?\027?@\000??)\023q???c1\ \036????_?^o?B?\036^\002???F\037????#?t9?&??|?w@\031 at a??!j?ah?\ ??H3??{?Fy\003???w\000?V??\007?\001\012?\000???\017?t?\005U?>??\021J??|!?a??z?'???????\ >??#t\002??h?3=\016\016C\002\006\004z?\013??U????c\020h?3\002?j:2??\037S\022emkP??nU\021?\021V?[?\006=\ gA?\"??\025???q3\0111????u&?\022m)FG?\034?!????\003??\014\037?\022???\023?Y?.E\021??\004?\0321R`?\ ?'a?\035??\0108??\001\005?,\005.h??\026\036?\002`?????\010?A85?\"?+\026J?????=?5eO?(??H?\025\022\015\ &?T\017?s?V??o1??\034\006??B\031\\?\013?X???????i#_?\030?\">?????k6?\023) ?\026\022\037??>?R\ h?\020???Ff&Jq?KoB?X?\002\015?E????MO\013\017g\034:?s?\020_\004*?a`?i?o\015S?O?!?5????\032\ ?/??(8??\014q\033M,???!(\014?i\003?#X?K??G??0\024\0229?\005\036?]?? ?jF?[?\033\011??%#??2ncx????V??\013??n?????+??A??\ C?E??x??\035D\0341i\010??q-?'??\0128?a???xL?|?2?A\036\012?L???T\020????G??(&??R\035\ {kh?\036,??j ???A\005r?E.F???#]????FH\001\030b?0\003P??? ???|\012?AR\032S\002\023??@>\002??Q&\001??\037?R\ ???R-?X(!#\001??cj|?O?1$\034\012??A??+?A?U?@6\024?nD9xl\005?!\007\030?\0076\031\016??4\004\010\002?\ ??b??\0069??B??\022???\005:h?+Y?$f??g\026\020??8A^\0024\004*?????[mf??%x?o??t\012\022\006?\ \001f?9P>\003?4]??\034\020\000\027?\"I?9?\\G???{:\032\025????s5LT9???V????@=?\001?yv????\ s?\036G??#\004=M???(?\022+\022\003\\?\002R=?[a?\003??P\014???L??\007\026g\000&,?,\003\022?\034?\000??U?\026<\036\ ?z?$????\000??(???X at 3\010?B\023?\000\021\034 at L?9?O?<%??`\032?? ?Fc?:%??\024?V\031n???,???\ d\035??$F???x?IY;n76\016+??|??y?\025?>?????U\034B8\"?\026?Y3????s4?V?\021\031?\037??\ \014???\013<\023?\003'n??\0212??1@?&W?@?H\000\000'k?p\005??C?Q??7?\003??\014?????*????\031?#?\ L????*\012]??\035?\012\026I??\007?\0242*V\011??\010\004\0278???????x-??xu\005A???\\\025???\003{?\025r{\013\ ?\006?2?\032??JT?????\015,e?qE???F=?l??u^?8? ??~?d??4??1JK?A???5?????\ `#?\012?|a*PL,=\016j)\\???'?>?l{?\021M?^?????q??*`\000f(?\020R??K?&?\001\026??[??\ m2???\025F??4s??l!????\012?+?_?I????3\026??9??qT???\035\017?&?\034ZA?\035g\005???%\0044\ ?*S?\017????????\005??\031??a???3G??|P?[\027?>???yH\002??a|'\004??f\001?\003?\000?((?G?\ zH;0?U*+8?E$tB?'\032?????{?BB?\006? \012??\013??M?\013\007???zh?\025\030>\033?7?&??!?3\003\ ???DX??f2o??%\033?x]?????$\030?TX at A????\011\000?B\003?x\020\033?A\006\030??a?\006??.??\025??3\ 0O(\033sY??\002???S??3\003?hi??\037\000????<\023De0d??;??\035?$ ?8x???G?\022?Y\037X1?U7\ ???oUZ?\031{???+?a???\0305M\023,N??2h??\004?\020?\007?TS???\007?e\022X@^pF\037\016?)\0036??@?\ x???Md?.?#???w?h??????QM?????8[?????FG???0??7(P\\??\027???t?????\ ?0\005?\026d?\034\021?`,??\027?\0348?Y4?r.64\026^?;H??e??D?%R,q?\036???^???J?}??{?\011\\\ \032n?\021???ab/Z??>?#%\001????\005???B?=O\02191?I\017LzB?P?KcGa0??\013,?+?ll?>j\ \025\010\023;\001?\0216?Z\\Q?L??Q??}t?\027\024??]a???Z?,{?c??\000\020????7??b]g`X???:.o\ ??8??.?9|\000?_q?U?U??vGD(,\036?????\022R\034??t?3??n4??!???a\027??\031??X????\ pu\002????\"1z\"??? ??\033J$d&?5?/\013?2???\0027?#\014?????K?????]K?L?@Vq\020??l\ ???\025?0?>\001h\000?????????\021DDk\\ 4\004ff????\005L\005????j?m??k?k`x?}\021w?p?]W\ )\025\027x(\001\012?p\007\000\021\"~??X\015?????K??2!???tr5???P???Ju??6\034?{?wxj\001?\005?\012\011?\ ??'Q^?E\\???N??F6v?????X\001J??2?\002qT?K?X?\"???^?\003??!?m??????d\022N??\ )u????\026?V\006(n\027???v\014?[x?R?s?O3??z*n?? ????#\ ??uX?????'???\014?1???zx?n?~??????O>b\015\010?G???M???xC?\007??S\036????Uu[\ ?x)PKo ???uF?pn|?|?\033???4~dC??d2i??\032??i??eM?{?>?\021????`?S???W\004\ {?\\?&\006?g??????q?????X???P??\011V\034??\\f?Z?u?%\005????1???\015?9?82[0??\036\ ?-?=??\030=?\027S??,?v?&?Sx??b?c\015??@????????1a[\027?\010\013Z?t?mB?????G[?T\ ?>\015????\003d?\024\02634\014?\026??F'?\016???:FN\006??=6sD*?????>?C??Z;??\034????\036???\ \023\014????@????????????\032VR-1?\001hc??u>?N\004?\003\015\036\034u?\035??6?'???FqydX7?Q?\ CZ??\011?8Tl??x???@???\033C??#\026?\001MDl9\\\027??????\014???????\025??\017??{??\035x??\ }????l\016q???)?9 .\035?\033?\007???M??\005\003??{??A?\036?.??????\\9???\006?\004;N\013??.G???06p????\ ????p?41???ys?H?\012}?\010+XEw?7??CU0?F??\030?V!\024?Z?v\012\025?R??`?m??w?|F?\ 7?/?q??2?{]???xdT_?6?&>\0323?EJ?)c^?L'\033??????XYj???P??????\022????\ 00??L???:\030v???\012??/???\027?^P?k@#Q@\007?????0\015?\031??R??Lc???\030\011?\015????O\ \\{?O???\022R7??`??d\032\012M??n???=??V????/???e?>???G????\033c:M???q?N??\ \010IWb????V$nZ(l9c?{>?????8p?\025????C??????v??`?E\024?\012??B1??;ja6\0379\ ????M`|\002\012???S?h?Zt?\002?\032A??????8?1?G`f?y? ??V??9???4jv\0372?\020\017?Q\ ??\001?#?x?\033\033???\005??7???????z6??N\004????\021???Z?;}?&?????bA\036e?\036t(??\ ?;?W??ht??/?/?_???O\011U\011?i??q????^?2X\\?|??w?H4?F??????K??\037???a\ ??9???\013q|`G???\021G???ON?????t]?k?~??^'\036?e\030?&84?\003??s???\ ???!??[?M%???m\\?????????\003U???D\000?sn?\014????SA??\036???????l\035??????\ ???\010??\016k{@?8EA??,??56`z???????????`?3LH]>9M\ nt???x?%\000?q?.\020?\001?\007\001?71g9???+\023??\001?\033\036u?*\006???1???q?? ?\005?\001???P_Y\ ??SW???^?0???-%\024\032c??gi?a???xr?l?IP??\011??V????b??\017?\024vU??H?vC?\ 'Y?\032?z{?s??.\020S??e???D?\033??w?1?S?}??s7I?dxOY???e?\016??*??:???0?g\ ?????????%?\003??\024|\011\007????$?\027\025\036??[??\034?Z??p???????]*??\026?\012??t??&? \ %\017Bk(?\037\005??^?\005?????\016?1?_??7??A?a-\025?{g3?x\017??J???\017?m??-??zsG???\ ???=?h?\030.??\006\035ocQ?\005???A?U^?!???x>%?z.dB?_?????y?O?f\030??sPX\013????\023o??\030???G?x??0?????\ ?\0269?}4/[??@??z??z????\015????r?Et?h?3^ua??%?)d7??\035\021?{Y.\022j?\030?\027'?\ 2}?\021v\033:??~?L??\010\0138??g:?x?z????&?t?????#\ +w?????w???&???y?R??KZ?P??\023'\020???09??Q!?j-?~!? \026?v?2Pl???z:n?\ ?\014?m\033??=\036???\007? n#E??\0159?\022???dx?\021????4\0063???j=??1U??Q?\030????D??\ o?l0\031?#??g?????\020\"???C?4\036??8\025\030??lE6??z\012??p???2vc??5\017?1?\026???3\ u?Ny?f`???`?\000\010_+??2?PG@?j?f??X?0?a?????~?\007?t\002??A}\003?\006O???l???\ ????n?\015?dx\020??\023??5t?8??p?O$}.??>Sy??D2??2?\013???9??F?????i4??W???@\ P?&?7???????M????E?+???????\024????\007?\023#f#']u6\016M?\034_??\030??L???y?>?\ ??????\000uH?5?a:?[?{?\013+?\021?") ### end --- NEW FILE: ui_psp.py --- # -*- coding: ISO-8859-1 -*- """Resource ui_psp (from file ui.psp)""" # written by resourcepackage: (1, 0, 0) source = 'ui.psp' package = 'spambayes.resources' data = "Paint Shop Pro Image File\012\032\000\000\000\000\000\005\000\000\000~BK\000\000\000.\000\000\000.\000\000\000?\001\000\000F\000\000\000j\ ?t?X<@\002\002\000\030\000\001\000\000\000\000\001\000`?\002\000\001\000\000\000\002\000\003\000\000%~BK\000\012\000\030\000\000\000~FL\000\001\000\016\000\000\000???\000\012\000\000\000\ \012\000\000\000\000\000~BK\000\001\0008\000\000\000~FL\000\001\000\004\000\000\000??'>~FL\000\002\000\004\000\000\000\021?}?~FL\000\006\000\004\000\000\000\001\000\000\000~F\ L\000\007\000\004\000\000\000\004\004\000\007~BK\000\020\000g\035\000\000\010\000\000\000\002\000\000\000~BK\000\021\000\030\000\000\000\030\000\000\000?\000\000\000\037\000\000\000\030\000\003\000\001\000\000\000\ \000\001\001\000~BK\000\021\000\030\000\000\000\030\000\000\000?\001\000\000F\000\000\000\030\000\003\000\001\000\000\000\000\001\000\000~BK\000\022\000?\012\000\000\016\000\000\000?\012\000\000?H\000\000\ \005\000????\000\020JFIF\000\001\001\000\001,\001,\000\000??\000C\000\002\001\001\001\001\001\002\001\001\001\002\002\002\002\002\004\003\002\002\002\002\005\004\004\003\004\006\005\006\006\006\005\006\ \006\006\007\011\010\006\007\011\007\006\006\010\013\010\011\012\012\012\012\012\006\010\013\014\013\012\014\011\012\012\012??\000C\001\002\002\002\002\002\002\005\003\003\005\012\007\006\007\012\012\012\012\012\012\012\012\012\012\ \012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012??\000\021\010\000\037\000?\003\001\"\000\002\021\001\003\021\001?\ ?\000\033\000\001\000\002\003\001\001\000\000\000\000\000\000\000\000\000\000\000\006\007\003\005\010\004\011??\0005\020\000\002\002\001\004\001\002\004\002\007\011\000\000\000\000\000\001\002\003\004\005\000\006\007\021\022\010\ !\023\024\"1\025Q\011\026\027#2A?8BUaqv?????\000\031\001\000\003\001\001\001\000\000\000\000\000\000\000\000\000\000\000\000\003\005\002\006\001??\000*\021\000\002\001\003\004\ \000\005\004\003\001\000\000\000\000\000\000\001\002\021\003\004!\000\005\0221\006\"AQa\023Bq?#2????\000\014\003\001\000\002\021\003\021\000?\000???}]???bmg?\ ?:2??5???Khb????uw??1?:?$x? ????_8}A~?o[?P???x{?,???????[??\ N?\0362G???\031\"?;?d?V2\004?c\022t#%z?\013??V?qR????q\001?pHe\007?\004}?r??\021??G7?M?s\ ?hS?if?\034?R\020?\004?!3???\037?\036^??????\017??Z???????\011???????t?)\0322?,k?b0z\ \012O?\001??\004j??\027???N*???4??????????N??{??\003?3??F?{??\001T\005\000\011???O???P?\ ??B at NfX?\000??? ?\003\002``j????m??????[?\024\022I????\004????5Z??d?O??F??????\ ?v??.~\000??*????? ???\020A??m=E????\036\034?q???\015????\004V??\034?????1??C2??C\ \033+???O~??yO??io^t?6$???Cj?IY?m?\"???>C?H???J?!\010`Y??\020?O?,?ox_a\ ??uv??Zq?\005?\016\026V9)???? (\004??\006'?7??je[Kr??!\013??4?#?\025??- \001?GzT?S!R\ +?-G<\023??C4.\031$B;\014?{\020A\004\021??MV^???up?????\026+??[9c'Gkcfi(??% ?\012??S\ \"?]??????\000??z?J?\020??Q?I^\037/??x????[=4?????&\004\017??>5?DI?\"r~O??]?O%N\\~F?S??6?x&?\ 2H?:*?}? ?A??\027??4p\037\037?\010wN???5\033?C\0126#???A?D@\033?\\\021??a}???????????\ ??TeV?\002@??;?\000t?????+?@??\022\001#?O_???f??fg?,???k???(?J??fj?7??/+\ ?\033?\011S?#O1_.?2?_s?\016?]*??\022i?Rq?\037?n?\032U?\025\024\020=??3?&??????k??\000???\023\015\ ???j?{\007I+R?V:??F>??E\012???(\003?k???R????????N?N????@\017?\003M4?I???M4\ h?Q\037?G\021????o?z??c\017?W??o?>W??????????|?~?/\037mK????\\[??NW?*`?*{\ \006;\007?\034\035&??\013??U\003q!??`?????=?4?M'N?M4??_??~BK\000\022\000\014\022\000\000\016\000\000\000?\021\000\000?q\001\ \000\010\000????\000\020JFIF\000\001\001\000\001,\001,\000\000??\000C\000\005\003\004\004\004\003\005\004\004\004\005\005\005\006\007\014\010\007\007\007\007\017\013\013\011\014\021\017\022\022\021\017\ \021\021\023\026\034\027\023\024\032\025\021\021\030!\030\032\035\035\037\037\037\023\027\"$\"\036$\034\036\037\036??\000C\001\005\005\005\007\006\007\016\010\010\016\036\024\021\024\036\036\036\036\036\036\036\036\036\ \036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036\036??\000\021\010\000F\001?\003\001\"\000\002\021\001\003\021\001\ ??\000\034\000\001\000\003\000\003\001\001\000\000\000\000\000\000\000\000\000\000\005\006\007\003\004\010\001\002??\000F\020\000\001\003\003\002\003\005\003\010\006\006\013\000\000\000\000\001\000\002\003\004\005\021\006\022\ \007!1\023\024\"AQ\0252a\010\026#Bq???3Vb???\027$&CR?78Ffuv???????\000\033\001\001\000\003\001\001\001\001\000\000\000\000\000\000\ \000\000\000\000\004\005\006\003\002\001\007??\0002\021\000\001\003\002\004\004\004\006\002\002\003\000\000\000\000\000\001\000\002\021\003\004\005!1Q\022\023Aa\"q??2R????\024B\006\025\ ?????\000\014\003\001\000\002\021\003\021\000?\000?Z\"\"\"\"\"\"(\015w?-Z:????L???\003O?g?\000????U?\006?{????K\ ????\035u??F?v(?Q\020??\031?i$?????g]D0\020's?Du?\026?\013i??1??????)h????????\ ??????\023?\034\020IC?W\017?P???S??~z????\017?\030??rSj?)S\ Q\03556??M4?\014?8??s??p\000\001?$?XCi\\fX}\012\013?' ??\024?\"(??\"*\005\004??j\033???K'gUQO\ t????'??R?\001????N:\022???\"??8:\016c??O2\007U\036?~Q\0222>???\002z+?/?s\\??????A?\ !}Q??DDDEX?k[m??R?Gq????w?(???R\011?\\?4\027`\022Z?H?0\0276??\026?????N????\007\ >\011'??-$????\034??\023???2\024?e\\S?\026??\013?%?????\021\024U%\021\026W??2[???k5???W\010|39\ ??\024N?\000\016G7\021?\0061???.?????*?d????,??+:\002?\021a?\016'?:?l??^?u?+MAn??=??\ \031\031???????>\032q\002??he}\033$????x???Z\017G4?y?\036_\0209)wX-??.q\000?dKH \036??[b??\ \025y ??`?\011??oDER??\021\021\021\021\021\021\021\021\021\021\021\026G??Uu?\027?)t???;?f???3>?-p???????~\ c|??\036/??\035??????zo?ZB?E??m?????N???=?????\001??h???\033??\032R?\ ?!p?6:????I\0076???\031??????(\037?8?;??;A\024??\033v???\026\017R???????????\021\026Mi?\ \021\021\024\006??v?!bu????G???????C???>_?U\003f?]???q\037P????yl6?)?\020D6:B?^?n\ !?q$?\006\0175c?f?f????*\015\035??N??T???c??<\034\016?0\017?\025\003R????6????ZoT?q?G?)\ k?c|R\006?\001\014.?G??\010$\022|??\014?\037E?????|?t???\021??\025\006#T????\000\004\016\037???]?\007#??>\ ??ZgL?X??u?&U\006?I_%`???q8\016kZ???0\\\036N\006pz-\002??\035)c?RX??o?F\007w?M?N??\ ????\006I???p???\037,n????l\002?T6??)\011??d??ry??\016???e???\000?[-\036????-??\016\031\ +*?t??^?\033???|?t????\\w=???`??j1Ju\005:L>0>\"?Cc|?\007????\0137????Q???\ i\004??dG?O??Zv??[?%???k????nFy9??k??\007??PZ\017K??\0155Oe?%??|??`?!??\ \000\000?\000\005:??\033?\006\002y\023(\00388??E?{c4?^???m-???*j!%?X?v??\034;?o23?[?6?d\ ?;??[()?\033<\000H\"?4??%????9\007??V???\035 at b\024?\011???\035\004??fc/E?????6\025\"@???D\ ??M\004???\010??kP?????m?GH-??r??:\0127g\033d???h\033?????????4?????\033=???p\006\ |\015qi?\0008S??5?t??9???}NJ\026\"?2???c-v??\002???=A???=???\031\023s$?x????q?$\ ?C?X????=\017\025)?n????J?J?x???ds\011qc??y\035??,?^??FK\023%??{\036???? ?????\ \007??\025\037?k??gWx%K???x?\007???3???\030?B??XY#?\001?\021??o?v?n??R???n?\000?[?Y?\ ?L?`\003?q???\005??w??z:?z 5?T??\001??\005c]{?\015\025???w\032:z?g??\031?\0221?9\031i\004\036|?\032\0259u\003?|?q?]???0???????\ M????-V?\012v?J?O\015\024l,?M??c,f2\017?\017,?s\035U\"\013??N?{??d??,????????\035??\003\014\ Q\035???!???#;N0?E?i\032??F???C???a?\022\036[???;?q??????\013m?????=??p?m5l\ ?u\0011?\007dN?????n?4\035? ??s?+?k?U#??f?u?'e?}\016c^??SqC?Ppx]?\0152?g?]F\ GN?\025nDEB??f\027?\010iK????Sp??z??*$lsD\032\034?\027\0203\0318??+OQ:??\015\037z6????o???\ &?X?#??2??%Y???{?T1\ ?I\036??\031\031\033\\??XIsq?\006?>x^?Z?j??\027j0?L????=?\036??7?[????]dZa?????DD\ X??DDDDDDDDDDDDE\037?KO?????i?]?y??????????H\"?????bW?1??!0????\ H????????i????T?\024?;?d?\016i?A\\???A??\020\016EB7Hi6K??K?\033&s?PD\017??L?\033\"?\ ?????\030kZ0\000?\005?E??jT??O?^YI??@\010?????????Y????{?$q?I\015#?c\0322\\?x?\003\ ?????j??n\030E\024?{E=\\??p?A!?\036?.#?\005i?????'Z\026?\\\035;e\032(.????\007h???9DDP\ \024?\\\027\032:k?\004?5??jj??\034????F\010\\???Zd/?\002 ???S??p=?[n??????:?Fv?4???\ F}f?'\016??\003/?U?[w\030?????S\003???\005\024\024?&?\022?\003[??\033??3???W?\021_[?m?*q???|3????3?FZNFA\007?S?\012?\024\\k\037Yp??Uu2c|??J??\000\001?\036g\000\001?+?+*???\ \\>?Z??\022rv?~U_F???2?-!?\014????R???(?V2??W??*c??????nA\007\016\034?A#?P?N\ ?6\013?F???_-??7T????U?W\006???\032I?H\031???\"R?e:??k?\033??\000)R???i\002\000;7??\021\025\ j?DDDDDDDDD_?cd?:)X???Z??d8\036??]?v\032?9?K?L3I????D\016\0040o?\\OW???p?\ ??\".???1???'??:?\\????(?????????b?W????????8GY\034??\033????E??\007\002D\ ?.\004?\001??p_???Q??Z.?EWGT?\036C k;???\002\013FH?\015?g???????Zm?\023TP[(?&??i \ ??t???\031?z??\014V????2?!M?\004\015?Pp?Z??x+??2s?dDEZ?\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\ \021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\ \021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\ \021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\021\027??~BK\000\003\0008\007\000\000~\ BK\000\004\000?\001\000\000?\000\000\000\012\000Background\001\000\000\000\000\000\000\000\000?\001\000\000F\000\000\000\000\000\000\000\000\000\000\000?\001\000\000F\000\000\000?\000\ \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000??\000\000??\000\000??\000\000??\000\000??\ \000\000??\000\000??\000\000??\000\000??\000\000??\010\000\000\000\001\000\003\000~BK\000\005\000L\000\000\000\020\000\000\000<\000\000\000?q\001\000\000\000\001\000x????\000\ \000\000\000? ?]?\010U\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?7\000\000\000??\003\000?%?\033~BK\000\005\000\ L\000\000\000\020\000\000\000<\000\000\000?q\001\000\000\000\002\000x????\000\000\000\000? ?]?\010U\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \000\000\000\000\000\000\000?7\000\000\000??\003\000?%?\033~BK\000\005\000L\000\000\000\020\000\000\000<\000\000\000?q\001\000\000\000\003\000x????\000\000\000\000? ?]\ ?\010U\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?7\000\000\000??\003\000?%?\033~BK\000\004\000?\005\000\000}\000\000\000\ \004\000Text\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000??\000\000??\000\000??\000\000??\000\000??\000\000??\000\000??\000\000??\000\000??\000\000?\ ?~BK\000\015\000\010\005\000\000\010\000\000\000\001\000\000\000~BK\000\016\000?\004\000\000\024\000\000\000\000\000\001\000\007\000\000\000\001\000\000\000\000\000\000\000U\000\000\000\000\000\000\000\000\000\000\ \000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\000\000\000\000\034@\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000B@\000\000\000\000\000\000\000\000\000\000\ \000\000\000\000\000\000\000\000\000\000\000\000??\010\000\000\000\016\000\000\000\006\000\000\000\003\000\010\000\000\000\000\000\000\000\006\000\000\000\002\000Y\000\000\000\010\000Webdings\000\000\000\000\ ?\001\000\000\002\000\000\0005\000\000\000\000UUUUUU5@\000\001\000\001\000\000\001??p=\012?\034@??p=\012?\034@\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\ ??\000\000\000\000\000\000\000$@~BK\000\017\000\022\000\000\000\006\000\000\000\001\000\014\000\000\000\000\000\000\000????~BK\000\017\000\022\000\000\000\006\000\000\000\001\000\014\000\000\000\000\ ?\000????~BK\000\023\000-\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \000\000\006\000\000\000\001\000\010\000\000\000a\000\000\000\006\000\000\000\002\000Y\000\000\000\010\000Webdings\000\000\000\000?\001\000\000\002\000\000\000%\000\000\000\000??????-\ @\000\001\000\001\000\000\001??p=\012?\034@??p=\012?\034@\000\000\000\000\000\000\000\000??\000\000\000\000\000\000??\000\000\000\000\000\000\000$@~BK\000\017\000\022\000\000\ \000\006\000\000\000\001\000\014\000\000\000\000\000\000\000????~BK\000\017\000\022\000\000\000\006\000\000\000\001\000\014\000\000\000\000?\000????~BK\000\023\000-\000\000\000-\000\000\ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\001\000\010\000\000\000N\000\000\000\006\000\000\000\ \001\000\010\000\000\000L\000\000\000\006\000\000\000\001\000\010\000\000\000i\000\000\000\006\000\000\000\002\000Y\000\000\000\010\000Webdings\000\000\000\000?\002\000\000\002\000\000\000%\000\000\000\ \000??????-@\000\001\000\001\000\000\001??p=\012?\034@??p=\012?\034@\000\000\000\000\000\000\000\000??\000\000\000\000\000\000??\000\000\000\000\000\000\000$@~\ BK\000\017\000\022\000\000\000\006\000\000\000\001\000\014\000\000\000\000\000\000\000????~BK\000\017\000\022\000\000\000\006\000\000\000\001\000\014\000\000\000\000?\000????~BK\000\023\ \000-\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\001\000\010\000\000\000\ ?\000\000\000\006\000\000\000\002\000Z\000\000\000\011\000Wingdings\000\000\000\000?\001\000\000\002\000\000\000%\000\000\000\000??????-@\000\001\000\001\000\000\001??p\ =\012?\034@??p=\012?\034@\000\000\000\000\000\000\000\000??\000\000\000\000\000\000??\000\000\000\000\000\000\000$@~BK\000\017\000\022\000\000\000\006\000\000\000\001\000\014\000\000\000\ \000\000\000\000????~BK\000\017\000\022\000\000\000\006\000\000\000\001\000\014\000\000\000\000?\000????~BK\000\023\000-\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\001\000\010\000\000\000C\000\000\000\006\000\000\000\001\000\010\000\000\000D\000\000\000\006\ \000\000\000\002\000Y\000\000\000\010\000Webdings\000\000\000\000?\001\000\000\002\000\000\000#\000\000\000\000??????+@\000\001\000\001\000\000\001??p=\012?\034@?\ ?p=\012?\034@\000\000\000\000\000\000\000\000??\000\000\000\000\000\000??\000\000\000\000\000\000\000$@~BK\000\017\000\022\000\000\000\006\000\000\000\001\000\014\000\000\000\000\000\000\000??\ ??~BK\000\017\000\022\000\000\000\006\000\000\000\001\000\014\000\000\000\000?\000????~BK\000\023\000-\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\001\000\010\000\000\000s\000\000\000\010\000\000\000\000\000\000\000~BK\000\006\000r\000\000\000$\000\000\ \000o\001\000\000\005\000\000\000?\001\000\000.\000\000\000\000\000\000\000\000\000\000\000)\000\000\000)\000\000\000\010\000\000\000\001\000\001\000~BK\000\005\000<\000\000\000\020\000\000\000,\000\000\0004\ \013\000\000\003\000\000\000x?J?G\034H???80oT???Q??\012G\025?*D(?I$\016?\000\000\000\000??\003\000?3C?" ### end From montanaro at users.sourceforge.net Wed May 23 04:18:03 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Tue, 22 May 2007 19:18:03 -0700 Subject: [Spambayes-checkins] spambayes/spambayes CoreUI.py, 1.1.2.3, 1.1.2.4 Options.py, 1.141.2.1, 1.141.2.2 Message-ID: <20070523021809.683F81E4005@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv9996/spambayes Modified Files: Tag: CORESVR CoreUI.py Options.py Log Message: now we can import a useless plugin Index: CoreUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Attic/CoreUI.py,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** CoreUI.py 22 May 2007 03:05:12 -0000 1.1.2.3 --- CoreUI.py 23 May 2007 02:18:01 -0000 1.1.2.4 *************** *** 100,104 **** ) ! # Like the above, but hese are the options that will be offered on the # advanced configuration page. adv_map = ( --- 100,104 ---- ) ! # Like the above, but these are the options that will be offered on the # advanced configuration page. adv_map = ( *************** *** 808,811 **** --- 808,812 ---- self.prepared = False self.can_stop = True + self.plugin = None # Unique names for cached messages - see `getNewMessageName()` below. Index: Options.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Options.py,v retrieving revision 1.141.2.1 retrieving revision 1.141.2.2 diff -C2 -d -r1.141.2.1 -r1.141.2.2 *** Options.py 18 May 2007 03:54:39 -0000 1.141.2.1 --- Options.py 23 May 2007 02:18:01 -0000 1.141.2.2 *************** *** 1295,1298 **** --- 1295,1304 ---- r"\w\w(?:_\w\w)?", RESTORE), ), + + "Plugin" : ( + ("x-module", _("Plugin module name"), "WebAppPlugin", + _("""The name of the plugin module for the core server."""), + r"[\w]+", DO_NOT_RESTORE), + ), } From montanaro at users.sourceforge.net Wed May 23 04:18:03 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Tue, 22 May 2007 19:18:03 -0700 Subject: [Spambayes-checkins] spambayes/scripts core_server.py, 1.1.2.1, 1.1.2.2 Message-ID: <20070523021809.621E71E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/scripts In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv9996/scripts Modified Files: Tag: CORESVR core_server.py Log Message: now we can import a useless plugin Index: core_server.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/scripts/Attic/core_server.py,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** core_server.py 18 May 2007 03:54:39 -0000 1.1.2.1 --- core_server.py 23 May 2007 02:18:00 -0000 1.1.2.2 *************** *** 59,65 **** Protocol plugin interface: - o POP3 - o NNTP o Classifier for web apps (e.g. Trac, Roundup, Moin) Web training interface: --- 59,65 ---- Protocol plugin interface: o Classifier for web apps (e.g. Trac, Roundup, Moin) + o POP3? + o NNTP? Web training interface: *************** *** 133,140 **** return '%s:%d' % (addr, port) def main(state): ! """Runs the proxy forever or until a 'KILL' command is received or someone hits Ctrl+Break.""" http_server = UserInterfaceServer(state.ui_port) http_server.register(CoreUserInterface(state)) --- 133,149 ---- return '%s:%d' % (addr, port) + def load_plugin(name): + try: + plugin = __import__(name) + except ImportError: + plugin = __import__("spambayes.%s" % name) + plugin = getattr(plugin, name) + return plugin.register() def main(state): ! """Runs the core server forever or until a 'KILL' command is received or someone hits Ctrl+Break.""" + state.plugin = load_plugin(options["Plugin", "x-module"]) + print ">>", state.plugin http_server = UserInterfaceServer(state.ui_port) http_server.register(CoreUserInterface(state)) *************** *** 201,203 **** if __name__ == '__main__': ! run() --- 210,215 ---- if __name__ == '__main__': ! try: ! run() ! except KeyboardInterrupt: ! print "bye!" From montanaro at users.sourceforge.net Wed May 23 04:19:04 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Tue, 22 May 2007 19:19:04 -0700 Subject: [Spambayes-checkins] spambayes/spambayes WebAppPlugin.py, NONE, 1.1.2.1 Message-ID: <20070523021908.5AEA01E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv10392/spambayes Added Files: Tag: CORESVR WebAppPlugin.py Log Message: now we can import a useless plugin --- NEW FILE: WebAppPlugin.py --- from CorePlugin import PlugIn, PlugInUI class WebAppUI(PlugInUI): pass def register(): return PlugIn("WebApp", WebAppUI()) From montanaro at users.sourceforge.net Thu May 24 05:14:43 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Wed, 23 May 2007 20:14:43 -0700 Subject: [Spambayes-checkins] spambayes/spambayes dnscache.py,1.3,1.3.2.1 Message-ID: <20070524031452.C27DF1E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv15971 Modified Files: Tag: CORESVR dnscache.py Log Message: Handful of changes I've been running with for quite awhile. The only truly functional change was to make MinTTL a global and set it to one day. It was set to 0. The other stuff: * print messages to stderr * use "not container" instead of "len(container) > 0" * be a bit less aggressive in our pruning Index: dnscache.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/dnscache.py,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -C2 -d -r1.3 -r1.3.2.1 *** dnscache.py 13 Aug 2006 02:05:43 -0000 1.3 --- dnscache.py 24 May 2007 03:14:41 -0000 1.3.2.1 *************** *** 23,29 **** kCheckForPruneEvery=20 ! kMaxTTL=60 * 60 * 24 * 7 # One week ! kPruneThreshold=1500 # May go over slightly; numbers chosen at random ! kPruneDownTo=1000 --- 23,32 ---- kCheckForPruneEvery=20 ! kMaxTTL=60 * 60 * 24 * 7 # One week ! # Some servers always return a TTL of zero. We'll hold onto data a bit ! # longer. ! kMinTTL=24 * 60 * 60 * 1 # one day ! kPruneThreshold=5000 # May go over slightly; numbers chosen at random ! kPruneDownTo=2500 *************** *** 89,97 **** self.dnsTimeout=10 - # Some servers always return a TTL of zero. - # In those cases, turning this up a bit is - # probably reasonable. - self.minTTL=0 - # end of user-settable attributes --- 92,95 ---- *************** *** 160,164 **** c=self.caches[answer.qType] c[answer.question].remove(answer) ! if len(c[answer.question])==0: del c[answer.question] --- 158,162 ---- c=self.caches[answer.qType] c[answer.question].remove(answer) ! if not c[answer.question]: del c[answer.question] *************** *** 180,184 **** c=self.caches[answer.qType] c[answer.question].remove(answer) ! if len(c[answer.question])==0: del c[answer.question] --- 178,182 ---- c=self.caches[answer.qType] c[answer.question].remove(answer) ! if not c[answer.question]: del c[answer.question] *************** *** 218,233 **** pass else: ! assert len(answers)>0 ! ind=0 ! # No guarantee that expire has already been done ! while ind> sys.stderr, "lookup failure:", question ! if not answers: del cacheToLookIn[question] else: *************** *** 250,275 **** except DNS.Base.DNSError,detail: if detail.args[0]<>"Timeout": ! print "Error, fixme",detail ! print "Question was",queryQuestion ! print "Origianal question was",question ! print "Type was",qType objs=[ lookupResult(qType,None,question,self.cacheErrorSecs+now,now) ] cacheToLookIn[question]=objs # Add to format for return? return self.formatForReturn(objs) except socket.gaierror,detail: ! print "DNS connection failure:", self.queryObj.ns, detail ! print "Defaults:", DNS.defaults objs=[] for answer in reply.answers: if answer["typename"]==qType: ! # PyDNS returns TTLs as longs but RFC 1035 says that the ! # TTL value is a signed 32-bit value and must be positive, ! # so it should be safe to coerce it to a Python integer. ! # And anyone who sets a time to live of more than 2^31-1 ! # seconds (68 years and change) is drunk. ! # Arguably, I ought to impose a maximum rather than continuing ! # with longs (int(long) returns long in recent versions of Python). ! ttl=max(min(int(answer["ttl"]),kMaxTTL),self.minTTL) # RFC 2308 says that you should cache an NXDOMAIN for the # minimum of the minimum field of the SOA record and the TTL --- 250,275 ---- except DNS.Base.DNSError,detail: if detail.args[0]<>"Timeout": ! print >> sys.stderr, "Error, fixme", detail ! print >> sys.stderr, "Question was", queryQuestion ! print >> sys.stderr, "Original question was", question ! print >> sys.stderr, "Type was", qType objs=[ lookupResult(qType,None,question,self.cacheErrorSecs+now,now) ] cacheToLookIn[question]=objs # Add to format for return? return self.formatForReturn(objs) except socket.gaierror,detail: ! print >> sys.stderr, "DNS connection failure:", self.queryObj.ns, detail ! print >> sys.stderr, "Defaults:", DNS.defaults objs=[] for answer in reply.answers: if answer["typename"]==qType: ! # PyDNS returns TTLs as longs but RFC 1035 says that the TTL ! # value is a signed 32-bit value and must be positive, so it ! # should be safe to coerce it to a Python integer. And ! # anyone who sets a time to live of more than 2^31-1 seconds ! # (68 years and change) is drunk. Arguably, I ought to ! # impose a maximum rather than continuing with longs ! # (int(long) returns long in recent versions of Python). ! ttl=max(min(int(answer["ttl"]),kMaxTTL),kMinTTL) # RFC 2308 says that you should cache an NXDOMAIN for the # minimum of the minimum field of the SOA record and the TTL *************** *** 279,288 **** objs.append(item) ! if len(objs)>0: cacheToLookIn[question]=objs return self.formatForReturn(objs) # Probably SERVFAIL or the like ! if len(reply.authority)==0: objs=[ lookupResult(qType,None,question,self.cacheErrorSecs+now,now) ] cacheToLookIn[question]=objs --- 279,288 ---- objs.append(item) ! if objs: cacheToLookIn[question]=objs return self.formatForReturn(objs) # Probably SERVFAIL or the like ! if not reply.authority: objs=[ lookupResult(qType,None,question,self.cacheErrorSecs+now,now) ] cacheToLookIn[question]=objs *************** *** 319,329 **** "www.seeputofor.com", "www.completegarbage.tv", "www.tradelinkllc.com"]: ! print "checking", host now=time.time() ips=c.lookup(host) ! print ips,time.time()-now now=time.time() ips=c.lookup(host) ! print ips,time.time()-now if ips: --- 319,329 ---- "www.seeputofor.com", "www.completegarbage.tv", "www.tradelinkllc.com"]: ! print >> sys.stderr, "checking", host now=time.time() ips=c.lookup(host) ! print >> sys.stderr, ips,time.time()-now now=time.time() ips=c.lookup(host) ! print >> sys.stderr, ips,time.time()-now if ips: *************** *** 331,340 **** now=time.time() name=c.lookup(ip,qType="PTR") ! print name,time.time()-now now=time.time() name=c.lookup(ip,qType="PTR") ! print name,time.time()-now else: ! print "unknown" c.close() --- 331,340 ---- now=time.time() name=c.lookup(ip,qType="PTR") ! print >> sys.stderr, name,time.time()-now now=time.time() name=c.lookup(ip,qType="PTR") ! print >> sys.stderr, name,time.time()-now else: ! print >> sys.stderr, "unknown" c.close() From montanaro at users.sourceforge.net Thu May 24 05:19:37 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Wed, 23 May 2007 20:19:37 -0700 Subject: [Spambayes-checkins] spambayes/spambayes CoreUI.py, 1.1.2.4, 1.1.2.5 Options.py, 1.141.2.2, 1.141.2.3 UserInterface.py, 1.61, 1.61.2.1 WebAppPlugin.py, 1.1.2.1, 1.1.2.2 Message-ID: <20070524031941.854471E4003@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv17145/spambayes Modified Files: Tag: CORESVR CoreUI.py Options.py UserInterface.py WebAppPlugin.py Log Message: A start on allowing plugin configuration. This revealed a chicken-and-egg situation. You can't load the plugin before you know what it is. (I suppose it really belongs in the basic configuration.) For the time being fall back to requiring it on the command line. Index: CoreUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Attic/CoreUI.py,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -C2 -d -r1.1.2.4 -r1.1.2.5 *** CoreUI.py 23 May 2007 02:18:01 -0000 1.1.2.4 --- CoreUI.py 24 May 2007 03:19:34 -0000 1.1.2.5 *************** *** 692,695 **** --- 692,708 ---- self._writePostamble() + def onPluginconfig(self): + html = self._buildConfigPage(self.plugin.plugin_map) + html.title = _('Home > Plugin Configuration') + html.pagename = _('> Plugin Configuration') + html.plugin_button.name.value = _("Back to basic configuration") + html.plugin_button.action = "config" + html.config_submit.value = _("Save plugin options") + html.restore.value = _("Restore plugin options defaults") + del html.exp_button + del html.adv_button + self.writeOKHeaders('text/html') + self.write(html) + def _makeMessageInfo(self, message): """Given an email.Message, return an object with subjectHeader, Index: Options.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Options.py,v retrieving revision 1.141.2.2 retrieving revision 1.141.2.3 diff -C2 -d -r1.141.2.2 -r1.141.2.3 *** Options.py 23 May 2007 02:18:01 -0000 1.141.2.2 --- Options.py 24 May 2007 03:19:34 -0000 1.141.2.3 *************** *** 1295,1304 **** r"\w\w(?:_\w\w)?", RESTORE), ), - - "Plugin" : ( - ("x-module", _("Plugin module name"), "WebAppPlugin", - _("""The name of the plugin module for the core server."""), - r"[\w]+", DO_NOT_RESTORE), - ), } --- 1295,1298 ---- Index: UserInterface.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/UserInterface.py,v retrieving revision 1.61 retrieving revision 1.61.2.1 diff -C2 -d -r1.61 -r1.61.2.1 *** UserInterface.py 28 Nov 2005 10:53:12 -0000 1.61 --- UserInterface.py 24 May 2007 03:19:34 -0000 1.61.2.1 *************** *** 820,823 **** --- 820,825 ---- elif parms["how"] == _("Save experimental options"): pmap = experimental_ini_map + elif parms["how"] == _("Save plugin options"): + pmap = self.plugin_ini_map del parms["how"] html = self._getHTMLClone() Index: WebAppPlugin.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Attic/WebAppPlugin.py,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** WebAppPlugin.py 23 May 2007 02:19:00 -0000 1.1.2.1 --- WebAppPlugin.py 24 May 2007 03:19:34 -0000 1.1.2.2 *************** *** 1,8 **** ! from CorePlugin import PlugIn, PlugInUI ! class WebAppUI(PlugInUI): ! pass def register(): ! return PlugIn("WebApp", WebAppUI()) --- 1,30 ---- ! from CorePlugin import Plugin, PluginUI ! from spambayes.OptionsClass import * ! from spambayes.Options import _ ! class WebAppUI(PluginUI): ! defaults = ( ! ("xmlrpc_path", _("XML-RPC path"), "/sbrpc", ! _("""The path to respond to."""), ! r"[\w]+", RESTORE), ! ("xmlrpc_host", _("XML-RPC host"), "localhost", ! _("""The host to listen on."""), ! SERVER, RESTORE), ! ("xmlrpc_port", _("XML-RPC port"), "8001", ! _("""The port to listen on."""), ! r"[\d]+", RESTORE), ! ) ! ! def __init__(self): ! PluginUI.__init__(self) ! # Configuration options we will offer to users. ! self.plugin_map = ( ! (_('XML-RPC Options'), None), ! ('Plugin', 'xmlrpc_path'), ! ('Plugin', 'xmlrpc_host'), ! ('Plugin', 'xmlrpc_port'), ! ) def register(): ! return Plugin("WebApp", WebAppUI()) From montanaro at users.sourceforge.net Thu May 24 05:19:37 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Wed, 23 May 2007 20:19:37 -0700 Subject: [Spambayes-checkins] spambayes/scripts core_server.py, 1.1.2.2, 1.1.2.3 Message-ID: <20070524031941.7935D1E4002@bag.python.org> Update of /cvsroot/spambayes/spambayes/scripts In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv17145/scripts Modified Files: Tag: CORESVR core_server.py Log Message: A start on allowing plugin configuration. This revealed a chicken-and-egg situation. You can't load the plugin before you know what it is. (I suppose it really belongs in the basic configuration.) For the time being fall back to requiring it on the command line. Index: core_server.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/scripts/Attic/core_server.py,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** core_server.py 23 May 2007 02:18:00 -0000 1.1.2.2 --- core_server.py 24 May 2007 03:19:34 -0000 1.1.2.3 *************** *** 19,22 **** --- 19,24 ---- options: -h : Displays this help message. + -m module : + Identify plugin module to use (required) -d FILE : use the named DBM database file -p FILE : the the named Pickle database file *************** *** 144,149 **** """Runs the core server forever or until a 'KILL' command is received or someone hits Ctrl+Break.""" - state.plugin = load_plugin(options["Plugin", "x-module"]) - print ">>", state.plugin http_server = UserInterfaceServer(state.ui_port) http_server.register(CoreUserInterface(state)) --- 146,149 ---- *************** *** 157,161 **** # Read the arguments. try: ! opts, args = getopt.getopt(sys.argv[1:], 'hbd:p:l:u:o:') except getopt.error, msg: print >> sys.stderr, str(msg) + '\n\n' + __doc__ --- 157,161 ---- # Read the arguments. try: ! opts, args = getopt.getopt(sys.argv[1:], 'hbd:p:l:u:o:m:') except getopt.error, msg: print >> sys.stderr, str(msg) + '\n\n' + __doc__ *************** *** 163,166 **** --- 163,167 ---- state = CoreState() + state.plugin = None for opt, arg in opts: *************** *** 178,181 **** --- 179,188 ---- elif opt == '-o': options.set_from_cmdline(arg, sys.stderr) + elif opt == '-m': + state.plugin = load_plugin(arg) + + if state.plugin is None: + print >> sys.stderr, __doc__ + sys.exit() state.db_name, state.use_db = storage.database_type(opts) From montanaro at users.sourceforge.net Thu May 24 05:19:37 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Wed, 23 May 2007 20:19:37 -0700 Subject: [Spambayes-checkins] spambayes/spambayes/core_resources ui.html, 1.1.2.1, 1.1.2.2 ui_html.py, 1.1.2.1, 1.1.2.2 Message-ID: <20070524031942.9AFC81E4002@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes/core_resources In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv17145/spambayes/core_resources Modified Files: Tag: CORESVR ui.html ui_html.py Log Message: A start on allowing plugin configuration. This revealed a chicken-and-egg situation. You can't load the plugin before you know what it is. (I suppose it really belongs in the basic configuration.) For the time being fall back to requiring it on the command line. Index: ui.html =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/core_resources/Attic/ui.html,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** ui.html 22 May 2007 03:02:58 -0000 1.1.2.1 --- ui.html 24 May 2007 03:19:34 -0000 1.1.2.2 *************** *** 679,682 **** --- 679,688 ---- +
+
+ +
+
+
Index: ui_html.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/core_resources/Attic/ui_html.py,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** ui_html.py 22 May 2007 03:02:58 -0000 1.1.2.1 --- ui_html.py 24 May 2007 03:19:34 -0000 1.1.2.2 *************** *** 145,155 **** +w?????w???&???y?R??KZ?P??\023'\020???09??Q!?j-?~!? \026?v?2Pl???z:n?\ ?\014?m\033??=\036???\007? n#E??\0159?\022???dx?\021????4\0063???j=??1U??Q?\030????D??\ ! o?l0\031?#??g?????\020\"???C?4\036??8\025\030??lE6??z\012??p???2vc??5\017?1?\026???3\ ! u?Ny?f`???`?\000\010_+??2?PG@?j?f??X?0?a?????~?\007?t\002??A}\003?\006O???l???\ ! ????n?\015?dx\020??\023??5t?8??p?O$}.??>Sy??D2??2?\013???9??F?????i4??W???@\ ! P?&?7???????M????E?+???????\024????\007?\023#f#']u6\016M?\034_??\030??L???y?>?\ ! ??????\000uH?5?a:?[?{?\013+?\021?") ### end --- 145,155 ---- +w?????w???&???y?R??KZ?P??\023'\020???09??Q!?j-?~!? \026?v?2Pl???z:n?\ ?\014?m\033??=\036???\007? n#E??\0159?\022???dx?\021????4\0063???j=??1U??Q?\030????D??\ ! o?l0\031?#??g?????\020\"???C?4\036??8\025\030??lE6?*\016\013??9+?<9??Z`Vj\016??;?v?g\ ! ???8?? ,???:??WC5?\\?jE:??\022????a??\037?\023\007\014?w\007?q?\0371\032?{?-??\021sL?\017\000???z\016h????\013?z\ ! ?\020??E???\037??\011??54?{n?a\023??\037n??\012$?0?\026?-%r*??A? Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv9617 Modified Files: ImageStripper.py Log Message: We don't really care *why* opening/loading an image fails. If the operation fails, the image is invalid, as far as we are concerned. Index: ImageStripper.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ImageStripper.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** ImageStripper.py 26 Mar 2007 07:50:31 -0000 1.14 --- ImageStripper.py 25 May 2007 08:18:21 -0000 1.15 *************** *** 143,147 **** image = Image.open(StringIO.StringIO(bytes)) image.load() ! except IOError: tokens.add("invalid-image:%s" % part.get_content_type()) continue --- 143,149 ---- image = Image.open(StringIO.StringIO(bytes)) image.load() ! except: ! # Any error whatsoever is reason for not looking further at ! # the image. tokens.add("invalid-image:%s" % part.get_content_type()) continue From montanaro at users.sourceforge.net Mon May 28 23:38:58 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Mon, 28 May 2007 14:38:58 -0700 Subject: [Spambayes-checkins] spambayes/spambayes CorePlugin.py, NONE, 1.1.2.1 XMLRPCPlugin.py, NONE, 1.1.2.1 Message-ID: <20070528213903.1D16F1E400B@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv27119/spambayes Added Files: Tag: CORESVR CorePlugin.py XMLRPCPlugin.py Log Message: mv WebAppPlugin to XMLRPCPlugin, add CorePlugin --- NEW FILE: CorePlugin.py --- """ Plugins for Core Server. """ __author__ = "Skip Montanaro Update of /cvsroot/spambayes/spambayes/spambayes/core_resources In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv16608/spambayes/core_resources Modified Files: Tag: CORESVR ui_html.py Log Message: more progress - sort of have an xmlrpc server running Index: ui_html.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/core_resources/Attic/ui_html.py,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** ui_html.py 24 May 2007 03:19:34 -0000 1.1.2.2 --- ui_html.py 29 May 2007 01:27:17 -0000 1.1.2.3 *************** *** 145,155 **** +w?????w???&???y?R??KZ?P??\023'\020???09??Q!?j-?~!? \026?v?2Pl???z:n?\ ?\014?m\033??=\036???\007? n#E??\0159?\022???dx?\021????4\0063???j=??1U??Q?\030????D??\ ! o?l0\031?#??g?????\020\"???C?4\036??8\025\030??lE6?*\016\013??9+?<9??Z`Vj\016??;?v?g\ ! ???8?? ,???:??WC5?\\?jE:??\022????a??\037?\023\007\014?w\007?q?\0371\032?{?-??\021sL?\017\000???z\016h????\013?z\ ! ?\020??E???\037??\011??54?{n?a\023??\037n??\012$?0?\026?-%r*??A??b???U\ ! g??\024??\0050?a???\031???\012??\002?U??X?:?????\036?e???\005w?H?") ### end From montanaro at users.sourceforge.net Tue May 29 03:27:20 2007 From: montanaro at users.sourceforge.net (Skip Montanaro) Date: Mon, 28 May 2007 18:27:20 -0700 Subject: [Spambayes-checkins] spambayes/spambayes CorePlugin.py, 1.1.2.1, 1.1.2.2 Options.py, 1.141.2.3, 1.141.2.4 XMLRPCPlugin.py, 1.1.2.1, 1.1.2.2 Message-ID: <20070529012727.8832C1E4009@bag.python.org> Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv16608/spambayes Modified Files: Tag: CORESVR CorePlugin.py Options.py XMLRPCPlugin.py Log Message: more progress - sort of have an xmlrpc server running Index: CorePlugin.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Attic/CorePlugin.py,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** CorePlugin.py 28 May 2007 21:38:53 -0000 1.1.2.1 --- CorePlugin.py 29 May 2007 01:27:17 -0000 1.1.2.2 *************** *** 3,6 **** --- 3,8 ---- """ + import sys + __author__ = "Skip Montanaro Update of /cvsroot/spambayes/website In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv8023 Modified Files: Tag: CORESVR faq.txt Log Message: Add Mark Hammond's response from the mailing list about installing with elevated privileges. Index: faq.txt =================================================================== RCS file: /cvsroot/spambayes/website/faq.txt,v retrieving revision 1.93 retrieving revision 1.93.2.1 diff -C2 -d -r1.93 -r1.93.2.1 *** faq.txt 13 May 2007 13:44:51 -0000 1.93 --- faq.txt 31 May 2007 11:43:17 -0000 1.93.2.1 *************** *** 294,297 **** --- 294,303 ---- http://mail.python.org/pipermail/spambayes-bugs/2007-January/004119.html + Note that you will probably have to execute the installer with elevated + privileges. Right-clicking on the EXE and selecting "Run as Administrator" + should work (and will be necessary even if you are logged in as an admin + user). + + Does SpamBayes work with Outlook Express? -----------------------------------------