From mhammond at users.sourceforge.net Thu May 1 04:54:20 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Thu May 1 06:54:23 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000 train.py,1.25,1.26 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000 In directory sc8-pr-cvs1:/tmp/cvs-serv10295 Modified Files: train.py Log Message: Save the database after an explicit train. Index: train.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/train.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** train.py 17 Mar 2003 01:24:28 -0000 1.25 --- train.py 1 May 2003 10:54:17 -0000 1.26 *************** *** 143,146 **** --- 143,148 ---- import filter filter.filterer(mgr, progress) + progress.set_status("Saving training database...") + mgr.Save() def main(): From mhammond at users.sourceforge.net Thu May 1 04:55:07 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Thu May 1 06:55:11 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000/installer spambayes_addin.spec, 1.3, 1.4 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000/installer In directory sc8-pr-cvs1:/tmp/cvs-serv10711 Modified Files: spambayes_addin.spec Log Message: Ignore the pywin.dialogs package. Index: spambayes_addin.spec =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/installer/spambayes_addin.spec,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** spambayes_addin.spec 18 Mar 2003 06:34:16 -0000 1.3 --- spambayes_addin.spec 1 May 2003 10:55:05 -0000 1.4 *************** *** 28,32 **** extras.append( ("default_bayes_customize.ini", join(PROJECT_ROOT, "default_bayes_customize.ini"), 'DATA') ) ! excludes = ['timer', 'dde', 'win32help', 'spambayes.compatsets'] a = Analysis([INSTALLER_ROOT+'/support/_mountzlib.py', --- 28,32 ---- extras.append( ("default_bayes_customize.ini", join(PROJECT_ROOT, "default_bayes_customize.ini"), 'DATA') ) ! excludes = ['timer', 'dde', 'win32help', 'spambayes.compatsets', 'pywin.dialogs'] a = Analysis([INSTALLER_ROOT+'/support/_mountzlib.py', From mhammond at users.sourceforge.net Thu May 1 05:46:53 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Thu May 1 07:46:59 2003 Subject: [Spambayes-checkins] spambayes/testtools urlslurper.py,1.1,1.2 Message-ID: Update of /cvsroot/spambayes/spambayes/testtools In directory sc8-pr-cvs1:/tmp/cvs-serv31445 Modified Files: urlslurper.py Log Message: * Fix globals statements - they are only necessary when not implicitly global (and 2.3 warns about them). Couple of these were fixed by putting __main__ code into a main() function (thereby making global necessary), and global dicts do not need 'global' as there is no assignment. ( Fixed import - testtools is not a package - at least my copy has no __init__.py * socket.error is a possible exception * Print slurp status to stderr, so redirection of stdout allows stat collection, but progress is still visible. Index: urlslurper.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/testtools/urlslurper.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** urlslurper.py 30 Apr 2003 06:43:28 -0000 1.1 --- urlslurper.py 1 May 2003 11:46:51 -0000 1.2 *************** *** 84,88 **** from __future__ import generators ! import urllib2 import sys import re --- 84,88 ---- from __future__ import generators ! import urllib2, socket import sys import re *************** *** 99,109 **** from spambayes.Options import options from spambayes.classifier import Classifier, Bayes - from testtools import timtest import spambayes - global cache_filename cache_filename = "url.pck" - - global proxy_info proxy_info = {} # Fill in the details here (and uncomment these lines) if you connect via --- 99,106 ---- from spambayes.Options import options from spambayes.classifier import Classifier, Bayes import spambayes + import timtest cache_filename = "url.pck" proxy_info = {} # Fill in the details here (and uncomment these lines) if you connect via *************** *** 116,122 **** #} - global only_slurp_base only_slurp_base = False - global url_dict url_dict = {} --- 113,117 ---- *************** *** 133,137 **** def spamprob(self, wordstream, evidence=False, time_limit=None): - global url_dict start_time = time.time() prob, clues = Classifier.spamprob(self, wordstream, True) --- 128,131 ---- *************** *** 167,171 **** else: if options["globals", "verbose"]: ! print "Slurping:", url, "..." try: f = urllib2.urlopen(url) --- 161,165 ---- else: if options["globals", "verbose"]: ! print >> sys.stderr, "Slurping:", url, "..." try: f = urllib2.urlopen(url) *************** *** 175,182 **** page = headers + "\r\n" + page if options["globals", "verbose"]: ! print "Slurped." ! except IOError: url_dict[url] = 0.5 ! print "Couldn't get", url if not url_dict.has_key(url) or url_dict[url] != 0.5: # Create a fake Message object since Tokenizer is --- 169,176 ---- page = headers + "\r\n" + page if options["globals", "verbose"]: ! print >> sys.stderr, "Slurped." ! except (IOError, socket.error): url_dict[url] = 0.5 ! print >> sys.stderr, "Couldn't get", url if not url_dict.has_key(url) or url_dict[url] != 0.5: # Create a fake Message object since Tokenizer is *************** *** 231,236 **** f.close() ! ! if __name__ == "__main__": import getopt from spambayes import msgs --- 225,229 ---- f.close() ! def main(): import getopt from spambayes import msgs *************** *** 249,262 **** sys.exit() elif opt == '-u': - global proxy_info proxy_info["user"] = arg elif opt == '-p': - global proxy_info proxy_info["pass"] = arg elif opt == '-a': - global proxy_info proxy_info["host"] = arg elif opt == '-o': - global proxy_info proxy_info["port"] = int(arg) elif opt == '-f': --- 242,251 ---- *************** *** 284,285 **** --- 273,277 ---- msgs.setparms(hamkeep, spamkeep, seed=seed) timtest.drive(nsets) + + if __name__ == "__main__": + main() From mhammond at users.sourceforge.net Thu May 1 17:09:23 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Thu May 1 19:09:27 2003 Subject: [Spambayes-checkins] spambayes/testtools urlslurper.py,1.2,1.3 Message-ID: Update of /cvsroot/spambayes/spambayes/testtools In directory sc8-pr-cvs1:/tmp/cvs-serv2431 Modified Files: urlslurper.py Log Message: I may have broken a global in my last checkin - sorry about that. Cache works again. Only slurp HTML content - avoid gifs etc Index: urlslurper.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/testtools/urlslurper.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** urlslurper.py 1 May 2003 11:46:51 -0000 1.2 --- urlslurper.py 1 May 2003 23:09:20 -0000 1.3 *************** *** 116,119 **** --- 116,123 ---- url_dict = {} + # Exception to raise when we should skip the URL + class IgnoreURLException(Exception): + pass + def body_tokens(msg): tokens = Tokenizer().tokenize_body(msg) *************** *** 164,167 **** --- 168,175 ---- try: f = urllib2.urlopen(url) + # Anything that isn't text/html is ingored + content_type = f.headers.get('content-type') + if not content_type.startswith("text/html"): + raise IgnoreURLException("content type='%s'" % (content_type,)) page = f.read() f.close() *************** *** 170,176 **** if options["globals", "verbose"]: print >> sys.stderr, "Slurped." ! except (IOError, socket.error): url_dict[url] = 0.5 ! print >> sys.stderr, "Couldn't get", url if not url_dict.has_key(url) or url_dict[url] != 0.5: # Create a fake Message object since Tokenizer is --- 178,184 ---- if options["globals", "verbose"]: print >> sys.stderr, "Slurped." ! except (IgnoreURLException, IOError, socket.error), details: url_dict[url] = 0.5 ! print >> sys.stderr, "Couldn't get %s (%s)" % (url, details) if not url_dict.has_key(url) or url_dict[url] != 0.5: # Create a fake Message object since Tokenizer is *************** *** 222,225 **** --- 230,234 ---- if os.path.exists(filename): f = file(filename, "r") + global url_dict url_dict = pickle.load(f) f.close() From ta-meyer at ihug.co.nz Fri May 2 12:34:20 2003 From: ta-meyer at ihug.co.nz (Tony Meyer) Date: Thu May 1 19:34:57 2003 Subject: [Spambayes-checkins] spambayes/testtools urlslurper.py,1.1,1.2 In-Reply-To: <1ED4ECF91CDED24C8D012BCF2B034F13015F27B4@its-xchg4.massey.ac.nz> Message-ID: <1ED4ECF91CDED24C8D012BCF2B034F13C8CAEE@its-xchg4.massey.ac.nz> > * Fix globals statements - they are only necessary when not > implicitly global (and 2.3 warns about them). 2.2.2 warned about them too, but I couldn't figure what it was I was doing wrong, and it seemed to still work, so... > ( Fixed > import - testtools is not a package - at least my copy has no > __init__.py Opps. This was a hangover from testing before I put the module in the testtools directory. I deleted the __init__.py file I created, but forgot to delete the .pyc one so it didn't show up in my testing. Thanks for the improvements :) =Tony Meyer From anadelonbrin at users.sourceforge.net Thu May 1 17:38:52 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Thu May 1 19:38:55 2003 Subject: [Spambayes-checkins] spambayes/testtools urlslurper.py,1.3,1.4 Message-ID: Update of /cvsroot/spambayes/spambayes/testtools In directory sc8-pr-cvs1:/tmp/cvs-serv10916/testtools Modified Files: urlslurper.py Log Message: Fix so that the default location for the url cache is more correctly the current working directory (os.path.exists wouldn't find it before, at least in my testing). Index: urlslurper.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/testtools/urlslurper.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** urlslurper.py 1 May 2003 23:09:20 -0000 1.3 --- urlslurper.py 1 May 2003 23:38:47 -0000 1.4 *************** *** 102,106 **** import timtest ! cache_filename = "url.pck" proxy_info = {} # Fill in the details here (and uncomment these lines) if you connect via --- 102,106 ---- import timtest ! cache_filename = os.getcwd() + os.sep + "url.pck" proxy_info = {} # Fill in the details here (and uncomment these lines) if you connect via From ta-meyer at ihug.co.nz Fri May 2 12:40:33 2003 From: ta-meyer at ihug.co.nz (Tony Meyer) Date: Thu May 1 19:42:53 2003 Subject: [Spambayes-checkins] spambayes/testtools urlslurper.py,1.2,1.3 In-Reply-To: <1ED4ECF91CDED24C8D012BCF2B034F13015F28DE@its-xchg4.massey.ac.nz> Message-ID: <1ED4ECF91CDED24C8D012BCF2B034F13C8CAEF@its-xchg4.massey.ac.nz> > Only slurp HTML content - avoid gifs etc Hmm. I should have thought of that. In your opinion, is it likely that this would effect the results? (i.e. if I scored a gif, would it come back outside the unsure range?). =Tony Meyer From tim at fourstonesExpressions.com Thu May 1 20:03:24 2003 From: tim at fourstonesExpressions.com (Tim Stone - Four Stones Expressions) Date: Thu May 1 20:03:50 2003 Subject: [Spambayes-checkins] spambayes/testtools urlslurper.py, 1.2, 1.3 In-Reply-To: <1ED4ECF91CDED24C8D012BCF2B034F13C8CAEF@its-xchg4.massey.ac.nz> Message-ID: <981X823XT5207410KIIEMISQ1ZONSO.3eb1b5cc@myst> 5/1/2003 6:40:33 PM, "Tony Meyer" wrote: >> Only slurp HTML content - avoid gifs etc > >Hmm. I should have thought of that. In your opinion, is it likely that >this would effect the results? (i.e. if I scored a gif, would it come >back outside the unsure range?). If you tried to tokenize a gif, I can't imagine what would happen. The other problem is that non-html files can be huge... could really muck things up... c'est moi - TimS http://www.fourstonesExpressions.com http://wecanstopspam.org There are 10 kinds of people in the world: those who understand binary, and those who don't. From anadelonbrin at users.sourceforge.net Thu May 1 22:05:14 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Fri May 2 00:05:17 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000 export.py,1.4,1.5 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000 In directory sc8-pr-cvs1:/tmp/cvs-serv26538/Outlook2000 Modified Files: export.py Log Message: Update readme.txt to include imapfilter information, and to reflect the recent Options.py changes. Correct a comment in Outlook2000\export.py Hopefully fix Options.py so that the temp file problem on linux goes away (someone tell me if this is not the case) Improve Options.py so that options use the same delimiter as when read on export, where possible. Renamed/moved several options, as discussed on the list. For the moment, you can still refer to these by the old names (no modules have been updated to use the new names yet). The convert_config_file script should also convert these (but this is as yet untested). This should be the last major change of Options.py necessary for some time (I hope!). Patched hammiefilter so that it still uses the same default filename for the storage database. THIS WILL FAIL IF THE USER HAS CHOSEN TO NAME THE FILE "hammie.db" AND OPTIONS.PY DOES THE IMPORT OF THEIR CONFIG FILE. To fix, undo the patch, or simply put a full pathname in the config file. Index: export.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/export.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** export.py 9 Mar 2003 23:21:54 -0000 1.4 --- export.py 2 May 2003 04:05:11 -0000 1.5 *************** *** 125,129 **** in the "Standard Test Data Setup" section. ! If 'directory' is not specified, '..\\Data' is assumed. If 'directory' exists, it will be recursively deleted before --- 125,129 ---- in the "Standard Test Data Setup" section. ! If 'directory' is not specified, '..\\testtools\Data' is assumed. If 'directory' exists, it will be recursively deleted before From anadelonbrin at users.sourceforge.net Thu May 1 22:05:14 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Fri May 2 00:05:17 2003 Subject: [Spambayes-checkins] spambayes README.txt, 1.47, 1.48 hammiefilter.py, 1.16, 1.17 Message-ID: Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv26538 Modified Files: README.txt hammiefilter.py Log Message: Update readme.txt to include imapfilter information, and to reflect the recent Options.py changes. Correct a comment in Outlook2000\export.py Hopefully fix Options.py so that the temp file problem on linux goes away (someone tell me if this is not the case) Improve Options.py so that options use the same delimiter as when read on export, where possible. Renamed/moved several options, as discussed on the list. For the moment, you can still refer to these by the old names (no modules have been updated to use the new names yet). The convert_config_file script should also convert these (but this is as yet untested). This should be the last major change of Options.py necessary for some time (I hope!). Patched hammiefilter so that it still uses the same default filename for the storage database. THIS WILL FAIL IF THE USER HAS CHOSEN TO NAME THE FILE "hammie.db" AND OPTIONS.PY DOES THE IMPORT OF THEIR CONFIG FILE. To fix, undo the patch, or simply put a full pathname in the config file. Index: README.txt =================================================================== RCS file: /cvsroot/spambayes/spambayes/README.txt,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** README.txt 11 Mar 2003 01:51:05 -0000 1.47 --- README.txt 2 May 2003 04:05:11 -0000 1.48 *************** *** 32,43 **** Uses ConfigParser to allow fiddling various aspects of the classifier, tokenizer, and test drivers. Create a file named bayescustomize.ini to ! alter the defaults; all options and their default values can be found ! in the string "defaults" near the top of Options.py, which is really ! an .ini file embedded in the module. Modules wishing to control ! aspects of their operation merely do from Options import options ! near the start, and consult attributes of options. As an alternative to bayescustomize.ini, you can set the environment --- 32,48 ---- Uses ConfigParser to allow fiddling various aspects of the classifier, tokenizer, and test drivers. Create a file named bayescustomize.ini to ! alter the defaults. Modules wishing to control aspects of their ! operation merely do from Options import options ! near the start, and consult attributes of options. To see what options ! are available, import Options.py and do ! ! print Options.options.display_full() ! ! This will print out a detailed description of each option, the allowed ! values, and so on. (You can pass in a section or section and option ! name to display_full if you don't want the whole list). As an alternative to bayescustomize.ini, you can set the environment *************** *** 114,117 **** --- 119,129 ---- A client for hammiesrv. + imapfilter.py + A spam-classifying and training application for use with IMAP servers. + You can specify folders that contain mail to train as ham/spam, and + folders that contain mail to classify, and the filter will do so. + Note that this is currently in very early development and not + recommended for production use. + Test Driver Core *************** *** 119,123 **** Tester.py A test-driver class that feeds streams of msgs to a classifier ! instance, and keeps track of right/wrong percentages, and lists of false positives and false negatives. --- 131,135 ---- Tester.py A test-driver class that feeds streams of msgs to a classifier ! instance, and keeps track of right/wrong percentages and lists of false positives and false negatives. Index: hammiefilter.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/hammiefilter.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** hammiefilter.py 28 Apr 2003 00:36:03 -0000 1.16 --- hammiefilter.py 2 May 2003 04:05:12 -0000 1.17 *************** *** 97,100 **** --- 97,109 ---- def __init__(self): options = Options.options + # This is a bit of a hack to counter the default for + # persistent_storage_file changing from ~/.hammiedb to hammie.db + # This will work unless a user: + # * had hammie.db as their value for persistent_storage_file, and + # * their config file was loaded by Options.py. + if options["hammiefilter", "persistent_storage_file"] == \ + options.default("Storage", "persistent_storage_file"): + options["hammiefilter", "persistent_storage_file"] = \ + "~/.hammiedb" options.merge_files(['/etc/hammierc', os.path.expanduser('~/.hammierc')]) From anadelonbrin at users.sourceforge.net Thu May 1 22:05:15 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Fri May 2 00:05:21 2003 Subject: [Spambayes-checkins] spambayes/spambayes Options.py,1.47,1.48 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv26538/spambayes Modified Files: Options.py Log Message: Update readme.txt to include imapfilter information, and to reflect the recent Options.py changes. Correct a comment in Outlook2000\export.py Hopefully fix Options.py so that the temp file problem on linux goes away (someone tell me if this is not the case) Improve Options.py so that options use the same delimiter as when read on export, where possible. Renamed/moved several options, as discussed on the list. For the moment, you can still refer to these by the old names (no modules have been updated to use the new names yet). The convert_config_file script should also convert these (but this is as yet untested). This should be the last major change of Options.py necessary for some time (I hope!). Patched hammiefilter so that it still uses the same default filename for the storage database. THIS WILL FAIL IF THE USER HAS CHOSEN TO NAME THE FILE "hammie.db" AND OPTIONS.PY DOES THE IMPORT OF THEIR CONFIG FILE. To fix, undo the patch, or simply put a full pathname in the config file. Index: Options.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Options.py,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** Options.py 28 Apr 2003 23:36:24 -0000 1.47 --- Options.py 2 May 2003 04:05:12 -0000 1.48 *************** *** 34,43 **** o str(Option) should really call Option.unconvert since this is what it does. Try putting that in and running all the tests. - o Each Option object has a delimiter attribute - this separates out - values when the Object can have multiple values and is in string - form. At the moment the only place this is set is in unconvert() - where it is set to the first valid character out of a list. It - would be nice if convert() set the delimiter (if it wasn't already) - so that Options would keep the one they start with. o [See also the __issues__ string.] o Suggestions? --- 34,37 ---- *************** *** 98,101 **** --- 92,146 ---- return not not val + # Backwards compatibility stuff - this will be removed at some point + # This table allows easy conversion from the (old_section, old_option) + # names to the (new_section, new_option) names. + conversion_table = {("Hammie", "clue_mailheader_cutoff"): + ("Headers", "clue_mailheader_cutoff"), + ("Hammie", "header_score_digits"): + ("Headers", "header_score_digits"), + ("Hammie", "header_score_logarithm"): + ("Headers", "header_score_logarithm"), + ("Hammie", "header_name"): + ("Headers", "classification_header_name"), + ("Hammie", "header_ham_string"): + ("Headers", "header_ham_string"), + ("Hammie", "header_spam_string"): + ("Headers", "header_spam_string"), + ("Hammie", "header_unsure_string"): + ("Headers", "header_unsure_string"), + ("Hammie", "trained_header"): + ("Headers", "trained_header_name"), + ("pop3proxy", "evidence_header_name"): + ("Headers", "evidence_header_name"), + ("pop3proxy", "mailid_header_name"): + ("Headers", "mailid_header_name"), + ("pop3proxy", "prob_header_name"): + ("Headers", "score_header_name"), + ("pop3proxy", "thermostat_header_name"): + ("Headers", "thermostat_header_name"), + ("pop3proxy", "include_evidence"): + ("Headers", "include_evidence"), + ("pop3proxy", "include_prob"): + ("Headers", "include_score"), + ("pop3proxy", "include_thermostat"): + ("Headers", "include_thermostat"), + ("pop3proxy", "ports"): + ("pop3proxy", "listen_ports"), + ("pop3proxy", "servers"): + ("pop3proxy", "remote_servers"), + ("smtpproxy", "ports"): + ("smtpproxy", "listen_ports"), + ("smtpproxy", "servers"): + ("smtpproxy", "remote_servers"), + ("hammiefilter", "persistent_storage_file"): + ("Storage", "persistent_storage_file"), + ("hammiefilter", "persistent_use_database"): + ("Storage", "persistent_use_database"), + ("pop3proxy", "persistent_storage_file"): + ("Storage", "persistent_storage_file"), + ("pop3proxy", "persistent_use_database"): + ("Storage", "persistent_use_database"), + } + # These are handy references to commonly used regex/tuples defining # permitted values. Although the majority of options use one of these, *************** *** 106,110 **** REAL = r"[\d]+[\.]?[\d]*" # likewise, a *positive* real BOOLEAN = (False, True) ! SERVER = r"[\w\.\-]+(:[\d]+)?" # in the form server:port PORT = r"[\d]+" EMAIL_ADDRESS = r"[\w\-\.]+@[\w\-\.]+" --- 151,155 ---- REAL = r"[\d]+[\.]?[\d]*" # likewise, a *positive* real BOOLEAN = (False, True) ! SERVER = r"([\w\.\-]+(:[\d]+)?)" # in the form server:port PORT = r"[\d]+" EMAIL_ADDRESS = r"[\w\-\.]+@[\w\-\.]+" *************** *** 329,333 **** ("show_histograms", "Show histograms", True, ! "",BOOLEAN, RESTORE), ("compute_best_cutoffs_from_histograms", "Compute best cutoffs from histograms", True, --- 374,379 ---- ("show_histograms", "Show histograms", True, ! """""", ! BOOLEAN, RESTORE), ("compute_best_cutoffs_from_histograms", "Compute best cutoffs from histograms", True, *************** *** 531,539 **** "Hammie": ( # The name of the header that hammie, pop3proxy, and any other spambayes # software, adds to emails in filter mode. This will definately contain # the "classification" of the mail, and may also (i.e. with hammie) # contain the score ! ("header_name", "Classification header name", "X-Spambayes-Classification", """Spambayes classifies each message by inserting a new header into the message. This header can then be used by your email client --- 577,632 ---- "Hammie": ( + ("debug_header", "Add debug header", False, + """Enable debugging information in the header.""", + BOOLEAN, RESTORE), + + ("debug_header_name", "Debug header name", "X-Spambayes-Debug", + """Name of a debugging header for spambayes hackers, showing the + strongest clues that have resulted in the classification in the + standard header.""", + HEADER_NAME, RESTORE), + + ("train_on_filter", "Train when filtering", False, + """Train when filtering? After filtering a message, hammie can then + train itself on the judgement (ham or spam). This can speed things up + with a procmail-based solution. If you do enable this, please make + sure to retrain any mistakes. Otherwise, your word database will + slowly become useless.""", + BOOLEAN, RESTORE), + ), + + # These options control where Spambayes data will be stored, and in + # what form. They are used by many Spambayes applications (including + # pop3proxy, smtpproxy, imapfilter and hammie), and mean that data + # (such as the message database) is shared between the applications. + # If this is not the desired behaviour, you must have a different + # value for each of these options in a configuration file that gets + # loaded by the appropriate application only. + "Storage" : ( + ("persistent_use_database", "", True, + """hammiefilter can use either a database (quick to score one message) + or a pickle (quick to train on huge amounts of messages). Set this to + True to use a database by default.""", + BOOLEAN, RESTORE), + + ("persistent_storage_file", "Storage file name", "hammie.db", + """Spambayes builds a database of information that it gathers + from incoming emails and from you, the user, to get better and + better at classifying your email. This option specifies the + name of the database file. If you don't give a full pathname, + the name will be taken to be relative to the current working + directory.""", + FILE_WITH_PATH, DO_NOT_RESTORE), + ), + + # These options control the various headers that some Spambayes + # applications add to incoming mail, including imapfilter, pop3proxy, + # and hammie. + "Headers" : ( # The name of the header that hammie, pop3proxy, and any other spambayes # software, adds to emails in filter mode. This will definately contain # the "classification" of the mail, and may also (i.e. with hammie) # contain the score ! ("classification_header_name", "Classification header name", "X-Spambayes-Classification", """Spambayes classifies each message by inserting a new header into the message. This header can then be used by your email client *************** *** 578,600 **** BOOLEAN, RESTORE), ! ("debug_header", "Add debug header", False, ! """Enable debugging information in the header.""", BOOLEAN, RESTORE), ! ! ("debug_header_name", "Debug header name", "X-Spambayes-Debug", ! """Name of a debugging header for spambayes hackers, showing the ! strongest clues that have resulted in the classification in the ! standard header.""", HEADER_NAME, RESTORE), ! ! ("train_on_filter", "Train when filtering", False, ! """Train when filtering? After filtering a message, hammie can then ! train itself on the judgement (ham or spam). This can speed things up ! with a procmail-based solution. If you do enable this, please make ! sure to retrain any mistakes. Otherwise, your word database will ! slowly become useless.""", BOOLEAN, RESTORE), ! ("trained_header", "Trained header name", "X-Spambayes-Trained", """When training on a message, the name of the header to add with how it was trained""", --- 671,714 ---- BOOLEAN, RESTORE), ! ("include_score", "Add probability (score) header", False, ! """You can have Spambayes insert a header with the calculated spam ! probability into each mail. If you can view headers with your ! mailer, then you can see this information, which can be interesting ! and even instructive if you're a serious Spambayes junkie.""", BOOLEAN, RESTORE), ! ! ("score_header_name", "Probability (score) header name", "X-Spambayes-Spam-Probability", ! """""", HEADER_NAME, RESTORE), ! ! ("include_thermostat", "Add level header", False, ! """You can have spambayes insert a header with the calculated spam ! probability, expressed as a number of '*'s, into each mail (the more ! '*'s, the higher the probability it is spam). If your mailer ! supports it, you can use this information to fine tune your ! classification of ham/spam, ignoring the classification given.""", BOOLEAN, RESTORE), ! ("thermostat_header_name", "Level header name", "X-Spambayes-Level", ! """""", ! HEADER_NAME, RESTORE), ! ! ("include_evidence", "Add evidence header", False, ! """You can have spambayes insert a header into mail, with the ! evidence that it used to classify that message (a collection of ! words with ham and spam probabilities). If you can view headers ! with your mailer, then this may give you some insight as to why ! a particular message was scored in a particular way.""", ! BOOLEAN, RESTORE), ! ! ("evidence_header_name", "Evidence header name", "X-Spambayes-Evidence", ! """""", ! HEADER_NAME, RESTORE), ! ! ("mailid_header_name", "Spambayes id header name", "X-Spambayes-MailId", ! """""", ! HEADER_NAME, RESTORE), ! ! ("trained_header_name", "Trained header name", "X-Spambayes-Trained", """When training on a message, the name of the header to add with how it was trained""", *************** *** 611,626 **** ), - "hammiefilter" : ( - ("persistent_use_database", "", True, - """hammiefilter can use either a database (quick to score one message) - or a pickle (quick to train on huge amounts of messages). Set this to - True to use a database by default.""", - BOOLEAN, RESTORE), - - ("persistent_storage_file", "", "~/.hammiedb", - """""", - FILE_WITH_PATH, DO_NOT_RESTORE), - ), - # pop3proxy settings - pop3proxy also respects the options in the Hammie # section, with the exception of the extra header details at the moment. --- 725,728 ---- *************** *** 630,634 **** # you must specify the same number of ports in pop3proxy_ports. "pop3proxy" : ( ! ("servers", "Servers", (), """The Spambayes POP3 proxy intercepts incoming email and classifies it before sending it on to your email client. You need to specify --- 732,736 ---- # you must specify the same number of ports in pop3proxy_ports. "pop3proxy" : ( ! ("remote_servers", "Servers", (), """The Spambayes POP3 proxy intercepts incoming email and classifies it before sending it on to your email client. You need to specify *************** *** 644,648 **** SERVER, DO_NOT_RESTORE), ! ("ports", "Ports", (), """Each POP3 server that is being monitored must be assigned to a 'port' in the Spambayes POP3 proxy. This port must be different for --- 746,750 ---- SERVER, DO_NOT_RESTORE), ! ("listen_ports", "Ports", (), """Each POP3 server that is being monitored must be assigned to a 'port' in the Spambayes POP3 proxy. This port must be different for *************** *** 673,689 **** PATH, DO_NOT_RESTORE), - ("persistent_use_database", "", True, - """""", - BOOLEAN, RESTORE), - - ("persistent_storage_file", "Storage file name", "hammie.db", - """Spambayes builds a database of information that it gathers - from incoming emails and from you, the user, to get better and - better at classifying your email. This option specifies the - name of the database file. If you don't give a full pathname, - the name will be taken to be relative to the current working - directory.""", - FILE_WITH_PATH, DO_NOT_RESTORE), - ("notate_to", "Notate to", False, """Some email clients (Outlook Express, for example) can only --- 775,778 ---- *************** *** 705,743 **** BOOLEAN, RESTORE), - ("include_prob", "Add probability header", False, - """You can have spambayes insert a header with the calculated spam - probability into each mail. If you can view headers with your - mailer, then you can see this information, which can be interesting - and even instructive if you're a serious spambayes junkie.""", - BOOLEAN, RESTORE), - - ("prob_header_name", "Probability header name", "X-Spambayes-Spam-Probability", - """""", - HEADER_NAME, RESTORE), - - ("include_thermostat", "Add level header", False, - """You can have spambayes insert a header with the calculated spam - probability, expressed as a number of '*'s, into each mail (the more - '*'s, the higher the probability it is spam). If your mailer - supports it, you can use this information to fine tune your - classification of ham/spam, ignoring the classification given.""", - BOOLEAN, RESTORE), - - ("thermostat_header_name", "Level header name", "X-Spambayes-Level", - """""", - HEADER_NAME, RESTORE), - - ("include_evidence", "Add evidence header", False, - """You can have spambayes insert a header into mail, with the - evidence that it used to classify that message (a collection of - words with ham and spam probabilities). If you can view headers - with your mailer, then this may give you some insight as to why - a particular message was scored in a particular way.""", - BOOLEAN, RESTORE), - - ("evidence_header_name", "Evidence header name", "X-Spambayes-Evidence", - """""", - HEADER_NAME, RESTORE), - ("cache_messages", "Cache messages", True, """You can disable the pop3proxy caching of messages. This --- 794,797 ---- *************** *** 762,769 **** ("header", "body"), True), - ("mailid_header_name", "Spambayes id header name", "X-Spambayes-MailId", - """""", - HEADER_NAME, RESTORE), - ("strip_incoming_mailids", "Strip incoming spambayes ids", False, """If you receive messages from other spambayes users, you might --- 816,819 ---- *************** *** 779,783 **** "smtpproxy" : ( ! ("servers", "Servers", (), """The Spambayes SMTP proxy intercepts outgoing email - if you forward mail to one of the addresses below, it is examined for an id --- 829,833 ---- "smtpproxy" : ( ! ("remote_servers", "Servers", (), """The Spambayes SMTP proxy intercepts outgoing email - if you forward mail to one of the addresses below, it is examined for an id *************** *** 795,799 **** SERVER, DO_NOT_RESTORE), ! ("ports", "Ports", (), """Each SMTP server that is being monitored must be assigned to a 'port' in the Spambayes SMTP proxy. This port must be different for --- 845,849 ---- SERVER, DO_NOT_RESTORE), ! ("listen_ports", "Ports", (), """Each SMTP server that is being monitored must be assigned to a 'port' in the Spambayes SMTP proxy. This port must be different for *************** *** 931,946 **** ("unsure_folder", "Folder for unsure messages", "", ! """""", IMAP_FOLDER, DO_NOT_RESTORE), ("spam_folder", "Folder for suspected spam", "", ! """""", IMAP_FOLDER, DO_NOT_RESTORE), ("ham_train_folders", "Folders with mail to be trained as ham", (), """Comma delimited list of folders that will be examined for messages ! to train as ham.""", IMAP_FOLDER, DO_NOT_RESTORE), ("spam_train_folders", "Folders with mail to be trained as spam", (), """Comma delimited list of folders that will be examined for messages ! to train as spam.""", IMAP_FOLDER, DO_NOT_RESTORE), ), } --- 981,1000 ---- ("unsure_folder", "Folder for unsure messages", "", ! """""", ! IMAP_FOLDER, DO_NOT_RESTORE), ("spam_folder", "Folder for suspected spam", "", ! """""", ! IMAP_FOLDER, DO_NOT_RESTORE), ("ham_train_folders", "Folders with mail to be trained as ham", (), """Comma delimited list of folders that will be examined for messages ! to train as ham.""", ! IMAP_FOLDER, DO_NOT_RESTORE), ("spam_train_folders", "Folders with mail to be trained as spam", (), """Comma delimited list of folders that will be examined for messages ! to train as spam.""", ! IMAP_FOLDER, DO_NOT_RESTORE), ), } *************** *** 1039,1043 **** def _split_values(self, value): # do the regex mojo here - # XXX use re.findall? try: r = re.compile(self.allowed_values) --- 1093,1096 ---- *************** *** 1053,1056 **** --- 1106,1112 ---- break vals += (m.group(),) + delimiter = s[i:i + m.start()] + if self.delimiter is None and delimiter != "": + self.delimiter = delimiter i += m.end() return vals *************** *** 1150,1154 **** # can have multiple values. Note that we have None at # the end so that this will crash and die if none of ! # the separators works if self.delimiter is None: if type(self.allowed_values) == types.TupleType: --- 1206,1210 ---- # can have multiple values. Note that we have None at # the end so that this will crash and die if none of ! # the separators works . if self.delimiter is None: if type(self.allowed_values) == types.TupleType: *************** *** 1175,1179 **** v = str(v) strval += v + self.delimiter ! strval = strval[:-1] # trailing seperator else: # Otherwise, we just hope str() will do the job --- 1231,1235 ---- v = str(v) strval += v + self.delimiter ! strval = strval[:-len(self.delimiter)] # trailing seperator else: # Otherwise, we just hope str() will do the job *************** *** 1301,1306 **** shutil.copyfile(filename, filename + ".bak") # copy the new file across ! shutil.copyfile(out.name, filename) out.close() def _add_missing(self, out, written, sect, vi, label=True): --- 1357,1364 ---- shutil.copyfile(filename, filename + ".bak") # copy the new file across ! f = file(filename) ! shutil.copyfileobj(out, f) out.close() + f.close() def _add_missing(self, out, written, sect, vi, label=True): *************** *** 1337,1344 **** # *** This will vanish soon, so do not make use of it in # new code *** old_name = section[0:1].lower() + section[1:] + "_" + option setattr(options, old_name, value) - old_name = option - setattr(options, old_name, value) def merge_files(self, file_list): --- 1395,1401 ---- # *** This will vanish soon, so do not make use of it in # new code *** + setattr(options, option, value) old_name = section[0:1].lower() + section[1:] + "_" + option setattr(options, old_name, value) def merge_files(self, file_list): *************** *** 1356,1367 **** if opt[:len(sect) + 1].lower() == sect.lower() + '_': opt = opt[len(sect)+1:] # end of backward compatibility guff ! if not self._options.has_key((sect, opt)): print "Invalid option %s in section %s in file %s" % \ (opt, sect, filename) else: ! if self.multiple_values_allowed(sect, opt): ! value = self.convert(sect, opt, value) ! self.set(sect, opt, self.convert(sect, opt, value)) # not strictly necessary, but convenient shortcuts to self._options --- 1413,1433 ---- if opt[:len(sect) + 1].lower() == sect.lower() + '_': opt = opt[len(sect)+1:] + if conversion_table.has_key((sect, opt)): + section, option = conversion_table[sect, opt] + else: + section = sect + option = opt # end of backward compatibility guff ! if not self._options.has_key((section, option)): print "Invalid option %s in section %s in file %s" % \ (opt, sect, filename) else: ! if self.multiple_values_allowed(section, option): ! value = self.convert(section, option, value) ! self.set(section, option, self.convert(section, option, ! value)) ! # backward compatibility guff ! self._oldset(sect, opt, value) ! # end of backward compatibility guff # not strictly necessary, but convenient shortcuts to self._options *************** *** 1400,1407 **** return self._options[sect, opt].unconvert() ! def get(self, sect=None, opt=None): '''Get an option.''' ! if sect is None or opt is None: ! return None return self._options[sect, opt].get() --- 1466,1473 ---- return self._options[sect, opt].unconvert() ! def get(self, sect, opt): '''Get an option.''' ! if conversion_table.has_key((sect, opt)): ! sect, opt = conversion_table[sect, opt] return self._options[sect, opt].get() *************** *** 1409,1416 **** return self.get(key[0], key[1]) ! def set(self, sect=None, opt=None, val=None): '''Set an option.''' ! if sect is None or opt is None: ! raise KeyError if self.is_valid(sect, opt, val): self._options[sect, opt].set(val) --- 1475,1482 ---- return self.get(key[0], key[1]) ! def set(self, sect, opt, val=None): '''Set an option.''' ! if conversion_table.has_key((sect, opt)): ! sect, opt = conversion_table[sect, opt] if self.is_valid(sect, opt, val): self._options[sect, opt].set(val) From anadelonbrin at users.sourceforge.net Thu May 1 22:17:09 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Fri May 2 00:17:15 2003 Subject: [Spambayes-checkins] spambayes/spambayes Options.py,1.48,1.49 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv29780/spambayes Modified Files: Options.py Log Message: A better fix for the temp file problem. This does seem to work, and the convert_config_file script does seem to convert old files, still. Since I can't test on other platforms, let me know if there is still a problem. Index: Options.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Options.py,v retrieving revision 1.48 retrieving revision 1.49 diff -C2 -d -r1.48 -r1.49 *** Options.py 2 May 2003 04:05:12 -0000 1.48 --- Options.py 2 May 2003 04:17:06 -0000 1.49 *************** *** 1286,1290 **** sectname = None optname = None ! out = TemporaryFile("w") if os.path.exists(filename): f = file(filename, "r") --- 1286,1290 ---- sectname = None optname = None ! out = TemporaryFile() if os.path.exists(filename): f = file(filename, "r") *************** *** 1357,1361 **** shutil.copyfile(filename, filename + ".bak") # copy the new file across ! f = file(filename) shutil.copyfileobj(out, f) out.close() --- 1357,1362 ---- shutil.copyfile(filename, filename + ".bak") # copy the new file across ! f = file(filename, "w") ! out.seek(0) shutil.copyfileobj(out, f) out.close() From anadelonbrin at users.sourceforge.net Fri May 2 22:07:06 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sat May 3 00:07:13 2003 Subject: [Spambayes-checkins] spambayes FAQ.txt,1.4,1.5 Message-ID: Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv28164 Modified Files: FAQ.txt Log Message: Remove OptionConfig as it is no longer used. Update the FAQ to include some information from tokenizer.py Fix invalid (renamed) options in ImapUI and ProxyUI. Index: FAQ.txt =================================================================== RCS file: /cvsroot/spambayes/spambayes/FAQ.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** FAQ.txt 20 Apr 2003 03:39:28 -0000 1.4 --- FAQ.txt 3 May 2003 04:07:03 -0000 1.5 *************** *** 101,102 **** --- 101,138 ---- working directory and your home directory for a bayescustomize.ini or .spambayesrc file (respectively). + + Q: The clues for my mail are all in lower case, but "FREE" is a much + better clue than "free". Why do you force everything into lower + case? + A: This was very carefully weighed up. On the positive side, removing + case does hide information (and we're not really sure what it does + to non-English languages), but on the negative side, it makes the + database a lot bigger, and requires more training. In the end, + testing with case removed resulted in no change in the false + positive rate, and a small reduction in the false negative rate, + so that's what we do. There is one exception: we keep case in + subject lines, because testing showed an improvement if we did + that. + + Q: Forget tokenising words - you should use character n-grams! + A: This was quite carefully tested. Character 3-grams gave five times + as many false positives, and twice as many false negatives as + splitting on whitespace (words). Character 5-grams came fairly + close to words with false positives, but the number of false + negatives was worse than with 3-grams. n-grams also creates many + more unique tokens, which means much slower operation. + + In addition, it's much harder to figure out *why* a message scored + as it did with n-grams. On the other hand, words are easy to + understand. + + There was, however, one area where n-grams were much better: detecting + spam in Asian languages. Since a 'word' in an Asian language message + ends up being an entire line, words don't work very well at all. + + Q: Why don't short words or long words show up in the clues? + A: Words less than 3 characters long are skipped, and words greater than + 12 characters long are converted into a special 'long-word' token. + These numbers (3 and 12) were determined by brute force testing, and + produced the best overall results (including compared to no upper + or lower limits). From anadelonbrin at users.sourceforge.net Fri May 2 22:07:06 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sat May 3 00:07:14 2003 Subject: [Spambayes-checkins] spambayes/spambayes ImapUI.py, 1.7, 1.8 ProxyUI.py, 1.4, 1.5 OptionConfig.py, 1.10, NONE Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv28164/spambayes Modified Files: ImapUI.py ProxyUI.py Removed Files: OptionConfig.py Log Message: Remove OptionConfig as it is no longer used. Update the FAQ to include some information from tokenizer.py Fix invalid (renamed) options in ImapUI and ProxyUI. Index: ImapUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ImapUI.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** ImapUI.py 24 Apr 2003 07:43:46 -0000 1.7 --- ImapUI.py 3 May 2003 04:07:04 -0000 1.8 *************** *** 78,90 **** ('imap', 'use_ssl'), ('Header Options', None), ! ('pop3proxy', 'notate_to'), ('pop3proxy', 'notate_subject'), ! ('pop3proxy', 'include_prob'), ! ('pop3proxy', 'include_thermostat'), ! ('pop3proxy', 'include_evidence'), ('pop3proxy', 'add_mailid_to'), ('pop3proxy', 'strip_incoming_mailids'), ('Statistics Options', None), ! ('pop3proxy', 'persistent_storage_file'), ('Categorization', 'ham_cutoff'), ('Categorization', 'spam_cutoff'), --- 78,90 ---- ('imap', 'use_ssl'), ('Header Options', None), ! ('Headers', 'notate_to'), ('pop3proxy', 'notate_subject'), ! ('Headers', 'include_score'), ! ('Headers', 'include_thermostat'), ! ('Headers', 'include_evidence'), ('pop3proxy', 'add_mailid_to'), ('pop3proxy', 'strip_incoming_mailids'), ('Statistics Options', None), ! ('Storage', 'persistent_storage_file'), ('Categorization', 'ham_cutoff'), ('Categorization', 'spam_cutoff'), Index: ProxyUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ProxyUI.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ProxyUI.py 24 Apr 2003 07:43:47 -0000 1.4 --- ProxyUI.py 3 May 2003 04:07:04 -0000 1.5 *************** *** 81,102 **** parm_ini_map = ( ('POP3 Proxy Options', None), ! ('pop3proxy', 'servers'), ! ('pop3proxy', 'ports'), ('pop3proxy', 'cache_messages'), ('Header Options', None), ! ('pop3proxy', 'notate_to'), ('pop3proxy', 'notate_subject'), ! ('pop3proxy', 'include_prob'), ! ('pop3proxy', 'include_thermostat'), ! ('pop3proxy', 'include_evidence'), ('pop3proxy', 'add_mailid_to'), ('pop3proxy', 'strip_incoming_mailids'), ('SMTP Proxy Options', None), ! ('smtpproxy', 'servers'), ! ('smtpproxy', 'ports'), ('smtpproxy', 'ham_address'), ('smtpproxy', 'spam_address'), ('Statistics Options', None), ! ('pop3proxy', 'persistent_storage_file'), ('Categorization', 'ham_cutoff'), ('Categorization', 'spam_cutoff'), --- 81,102 ---- parm_ini_map = ( ('POP3 Proxy Options', None), ! ('pop3proxy', 'remote_servers'), ! ('pop3proxy', 'listen_ports'), ('pop3proxy', 'cache_messages'), ('Header Options', None), ! ('Headers', 'notate_to'), ('pop3proxy', 'notate_subject'), ! ('Headers', 'include_score'), ! ('Headers', 'include_thermostat'), ! ('Headers', 'include_evidence'), ('pop3proxy', 'add_mailid_to'), ('pop3proxy', 'strip_incoming_mailids'), ('SMTP Proxy Options', None), ! ('smtpproxy', 'remote_servers'), ! ('smtpproxy', 'listen_ports'), ('smtpproxy', 'ham_address'), ('smtpproxy', 'spam_address'), ('Statistics Options', None), ! ('Storage', 'persistent_storage_file'), ('Categorization', 'ham_cutoff'), ('Categorization', 'spam_cutoff'), --- OptionConfig.py DELETED --- From mhammond at users.sourceforge.net Sat May 3 06:22:02 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Sat May 3 08:22:05 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000 export.py,1.5,1.6 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000 In directory sc8-pr-cvs1:/tmp/cvs-serv17835 Modified Files: export.py Log Message: Correct usage info wrt default directory Index: export.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/export.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** export.py 2 May 2003 04:05:11 -0000 1.5 --- export.py 3 May 2003 12:21:59 -0000 1.6 *************** *** 5,8 **** --- 5,9 ---- files_per_directory = 400 + default_directory = "..\\testtools\\Data" def BuildBuckets(manager): *************** *** 99,103 **** if len(args)==0: ! directory = os.path.join(os.path.dirname(sys.argv[0]), "..\\testtools\\Data") else: directory = args[0] --- 100,104 ---- if len(args)==0: ! directory = os.path.join(os.path.dirname(sys.argv[0]), default_directory) else: directory = args[0] *************** *** 125,133 **** in the "Standard Test Data Setup" section. ! If 'directory' is not specified, '..\\testtools\Data' is assumed. If 'directory' exists, it will be recursively deleted before the export (but you will be asked to confirm unless -q is given).""" \ ! % (os.path.basename(sys.argv[0]), files_per_directory) sys.exit(1) --- 126,134 ---- in the "Standard Test Data Setup" section. ! If 'directory' is not specified, '%s' is assumed. If 'directory' exists, it will be recursively deleted before the export (but you will be asked to confirm unless -q is given).""" \ ! % (os.path.basename(sys.argv[0]), files_per_directory, default_directory) sys.exit(1) From mhammond at users.sourceforge.net Sat May 3 06:36:51 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Sat May 3 08:36:55 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000 addin.py, 1.54, 1.55 manager.py, 1.55, 1.56 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000 In directory sc8-pr-cvs1:/tmp/cvs-serv24486 Modified Files: addin.py manager.py Log Message: Fix: 715248 - Pickle classifier should save to a temp file firs and 731538 - SpamBayes not filtering messages. Pickles are saved to a temp file first, and also as the dialog is dismissed rather than outlook shutdown (whch was probably the real cause of the error - user powering off before Outlook shutdown complete) Also formalized error reporting, and created special handing for "starup errors" - only the first is reported to the user (with a warning to reconfigure) and the plugin is disabled - the rest are simply logged to the log. Index: addin.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/addin.py,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** addin.py 19 Apr 2003 02:26:36 -0000 1.54 --- addin.py 3 May 2003 12:36:49 -0000 1.55 *************** *** 21,25 **** import pythoncom from win32com.client import constants, getevents - import win32ui import win32gui, win32con, win32clipboard # for button images! --- 21,24 ---- *************** *** 349,353 **** spam_folder = msgstore.GetFolder(spam_folder_id) if not spam_folder: ! win32ui.MessageBox("You must configure the Spam folder", "Invalid Configuration") return --- 348,352 ---- spam_folder = msgstore.GetFolder(spam_folder_id) if not spam_folder: ! self.manager.ReportError("You must configure the Spam folder", "Invalid Configuration") return *************** *** 535,539 **** sel = explorer.Selection if sel.Count > 1 and not allow_multi: ! win32ui.MessageBox("Please select a single item", "Large selection") return None --- 534,538 ---- sel = explorer.Selection if sel.Count > 1 and not allow_multi: ! self.manager.ReportError("Please select a single item", "Large selection") return None *************** *** 546,550 **** if len(ret) == 0: ! win32ui.MessageBox("No mail items are selected", "No selection") return None if allow_multi: --- 545,549 ---- if len(ret) == 0: ! self.manager.ReportError("No mail items are selected", "No selection") return None if allow_multi: *************** *** 705,718 **** self.UpdateFolderHooks() except: ! import traceback ! print "Error installing folder hooks." ! traceback.print_exc() ! self.manager.config.filter.enabled = False ! self.manager.SaveConfig() ! win32ui.MessageBox( ! "There was an error initializing the Spam plugin\r\n\r\n" ! "Spam filtering has been disabled. Please re-configure\r\n" ! "and re-enable this plugin", ! "Anti-Spam plugin") def UpdateFolderHooks(self): --- 704,709 ---- self.UpdateFolderHooks() except: ! self.manager.ReportFatalStartupError( ! "Could not watch the specified folders") def UpdateFolderHooks(self): Index: manager.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/manager.py,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** manager.py 9 Mar 2003 23:55:27 -0000 1.55 --- manager.py 3 May 2003 12:36:49 -0000 1.56 *************** *** 6,10 **** import errno import shutil ! import win32api, win32con import win32com.client --- 6,10 ---- import errno import shutil ! import win32api, win32con, win32ui import win32com.client *************** *** 78,81 **** --- 78,97 ---- pass + # Function to "safely" save a pickle, only overwriting + # the existing file after a successful write. + def SavePickle(what, filename): + temp_filename = filename + ".tmp" + file = open(temp_filename,"wb") + try: + cPickle.dump(what, file, 1) + finally: + file.close() + # now rename to the correct file. + try: + os.unlink(filename) + except os.error: + pass + os.rename(temp_filename, filename) + # Base class for our "storage manager" - we choose between the pickle # and DB versions at runtime. As our bayes uses spambayes.storage, *************** *** 109,113 **** return {} def store_mdb(self, mdb): ! cPickle.dump(mdb, open(self.mdb_filename,"wb"), 1) def close_mdb(self, mdb): pass --- 125,129 ---- return {} def store_mdb(self, mdb): ! SavePickle(mdb, self.mdb_filename) def close_mdb(self, mdb): pass *************** *** 136,139 **** --- 152,157 ---- class BayesManager: def __init__(self, config_base="default", outlook=None, verbose=1): + self.reported_startup_error = False + self.config = None self.addin = None self.verbose = verbose *************** *** 166,169 **** --- 184,221 ---- self.message_store = msgstore.MAPIMsgStore(outlook) + # Report a message to the user - should only be used for pretty serious errors + # hence we also print a traceback. + def ReportError(self, message, title = None): + import traceback + print "ERROR:", message + traceback.print_exc() + if title is None: + title = "SpamBayes Anti-Spam plugin" + win32ui.MessageBox(message, title) + + # Report a super-serious startup error to the user. + # This should only be used when SpamBayes was previously working, but a + # critical error means we are probably not working now. + # We just report the first such error - subsequent ones are likely a result of + # the first - hence, this must only be used for startup errors. + def ReportFatalStartupError(self, message): + if not self.reported_startup_error: + self.reported_startup_error = True + full_message = \ + "There was an error initializing the Spam plugin.\r\n\r\n" \ + "Spam filtering has been disabled. Please re-configure\r\n" \ + "and re-enable this plugin\r\n\r\n" \ + "Error details:\r\n" + message + # Disable the plugin + if self.config is not None: + self.config.filter.enabled = False + self.ReportError(full_message) + else: + # We have reported the error, but for the sake of the log, we + # still want it logged there. + import traceback + print "ERROR:", message + traceback.print_exc() + # Outlook used to give us thread grief - now we avoid Outlook # from threads, but this remains a worthwhile abstraction. *************** *** 311,317 **** print "Loaded bayes database from '%s'" % (self.db_manager.bayes_filename,) except: ! print "Failed to load bayes database" ! import traceback ! traceback.print_exc() try: message_db = self.db_manager.open_mdb() --- 363,367 ---- print "Loaded bayes database from '%s'" % (self.db_manager.bayes_filename,) except: ! self.ReportFatalStartupError("Failed to load bayes database") try: message_db = self.db_manager.open_mdb() *************** *** 320,326 **** pass except: ! print "Failed to load bayes message database" ! import traceback ! traceback.print_exc() if bayes is None or message_db is None: self.bayes = bayes --- 370,374 ---- pass except: ! self.ReportFatalStartupError("Failed to load bayes message database") if bayes is None or message_db is None: self.bayes = bayes *************** *** 358,366 **** print "Loaded configuration from '%s':" % self.config_filename ret._dump() - except (AttributeError, ImportError): - ret = config.ConfigurationRoot() - print "FAILED to load configuration from '%s' - using default:" % (self.config_filename,) - import traceback - traceback.print_exc() except IOError, details: # File-not-found - less serious. --- 406,409 ---- *************** *** 369,372 **** --- 412,421 ---- # filename included in exception! print "IOError loading configuration (%s) - using default:" % (details) + except: + # Any other error loading configuration is nasty, but should not + # cause a fatal error. + msg = "FAILED to load configuration from '%s'" % (self.config_filename,) + self.ReportFatalStartupError(msg) + ret = config.ConfigurationRoot() return ret *************** *** 407,411 **** self.config._dump() print " ->", self.config_filename ! cPickle.dump(self.config, open(self.config_filename,"wb"), 1) def Save(self): --- 456,460 ---- self.config._dump() print " ->", self.config_filename ! SavePickle(self.config, self.config_filename) def Save(self): *************** *** 465,468 **** --- 514,519 ---- d = dialogs.ManagerDialog.ManagerDialog(self, do_train, do_filter, define_filter) d.DoModal() + # And re-save now, just incase Outlook dies on the way down. + self.SaveConfig() _mgr = None From mhammond at users.sourceforge.net Sat May 3 07:15:30 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Sat May 3 09:15:35 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000 tester.py,1.6,1.7 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000 In directory sc8-pr-cvs1:/tmp/cvs-serv4372 Modified Files: tester.py Log Message: Allow test suite to work with bsddb3 or bsddb Index: tester.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/tester.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** tester.py 20 Mar 2003 12:07:59 -0000 1.6 --- tester.py 3 May 2003 13:15:27 -0000 1.7 *************** *** 38,42 **** def DBExtractor(bayes): ! import bsddb key = bayes.dbm.first()[0] if key not in ["saved state"]: --- 38,48 ---- def DBExtractor(bayes): ! # We use bsddb3 now if we can ! try: ! import bsddb3 as bsddb ! bsddb_error = bsddb.DBNotFoundError ! except ImportError: ! import bsddb ! bsddb_error = bsddb.error key = bayes.dbm.first()[0] if key not in ["saved state"]: *************** *** 46,49 **** --- 52,57 ---- key = bayes.dbm.next()[0] except bsddb.error: + break + except bsddb_error: break if key not in ["saved state"]: From anadelonbrin at users.sourceforge.net Sat May 3 16:16:33 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sat May 3 18:16:36 2003 Subject: [Spambayes-checkins] spambayes/spambayes ImapUI.py, 1.8, 1.9 ProxyUI.py, 1.5, 1.6 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv27384/spambayes Modified Files: ImapUI.py ProxyUI.py Log Message: Fix invalid (renamed) options in ImapUI and ProxyUI that were missed from the last checkin. Index: ImapUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ImapUI.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** ImapUI.py 3 May 2003 04:07:04 -0000 1.8 --- ImapUI.py 3 May 2003 22:16:30 -0000 1.9 *************** *** 78,82 **** ('imap', 'use_ssl'), ('Header Options', None), ! ('Headers', 'notate_to'), ('pop3proxy', 'notate_subject'), ('Headers', 'include_score'), --- 78,82 ---- ('imap', 'use_ssl'), ('Header Options', None), ! ('pop3proxy', 'notate_to'), ('pop3proxy', 'notate_subject'), ('Headers', 'include_score'), Index: ProxyUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ProxyUI.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ProxyUI.py 3 May 2003 04:07:04 -0000 1.5 --- ProxyUI.py 3 May 2003 22:16:30 -0000 1.6 *************** *** 85,89 **** ('pop3proxy', 'cache_messages'), ('Header Options', None), ! ('Headers', 'notate_to'), ('pop3proxy', 'notate_subject'), ('Headers', 'include_score'), --- 85,89 ---- ('pop3proxy', 'cache_messages'), ('Header Options', None), ! ('pop3proxy', 'notate_to'), ('pop3proxy', 'notate_subject'), ('Headers', 'include_score'), *************** *** 471,476 **** # check for equal number of pop3servers and ports ! slist = list(parms['pop3proxy_servers']) ! plist = list(parms['pop3proxy_ports']) if len(slist) != len(plist): errmsg += '
  • The number of POP3 proxy ports specified ' + \ --- 471,476 ---- # check for equal number of pop3servers and ports ! slist = list(parms['pop3proxy_remote_servers']) ! plist = list(parms['pop3proxy_listen_ports']) if len(slist) != len(plist): errmsg += '
  • The number of POP3 proxy ports specified ' + \ *************** *** 488,493 **** # check for equal number of smtpservers and ports ! slist = list(parms['smtpproxy_servers']) ! plist = list(parms['smtpproxy_ports']) if len(slist) != len(plist): errmsg += '
  • The number of SMTP proxy ports specified ' + \ --- 488,493 ---- # check for equal number of smtpservers and ports ! slist = list(parms['smtpproxy_remote_servers']) ! plist = list(parms['smtpproxy_listen_ports']) if len(slist) != len(plist): errmsg += '
  • The number of SMTP proxy ports specified ' + \ From anadelonbrin at users.sourceforge.net Sat May 3 21:05:37 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sat May 3 23:05:46 2003 Subject: [Spambayes-checkins] spambayes/spambayes Corpus.py, 1.6, 1.7 FileCorpus.py, 1.3, 1.4 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv8809/spambayes Modified Files: Corpus.py FileCorpus.py Log Message: Updated to use new options style (almost all "globals":"verbose"). Index: Corpus.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Corpus.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Corpus.py 26 Feb 2003 04:36:21 -0000 1.6 --- Corpus.py 4 May 2003 03:05:33 -0000 1.7 *************** *** 123,127 **** '''Add a Message to this corpus''' ! if options.verbose: print 'adding message %s to corpus' % (message.key()) --- 123,127 ---- '''Add a Message to this corpus''' ! if options["globals", "verbose"]: print 'adding message %s to corpus' % (message.key()) *************** *** 142,146 **** key = message.key() ! if options.verbose: print 'removing message %s from corpus' % (key) self.unCacheMessage(key) --- 142,146 ---- key = message.key() ! if options["globals", "verbose"]: print 'removing message %s from corpus' % (key) self.unCacheMessage(key) *************** *** 160,164 **** key = message.key() ! if options.verbose: print 'placing %s in corpus cache' % (key) --- 160,164 ---- key = message.key() ! if options["globals", "verbose"]: print 'placing %s in corpus cache' % (key) *************** *** 177,181 **** # This method should probably not be overridden ! if options.verbose: print 'Flushing %s from corpus cache' % (key) --- 177,181 ---- # This method should probably not be overridden ! if options["globals", "verbose"]: print 'Flushing %s from corpus cache' % (key) *************** *** 269,273 **** for msg in self: if msg.createTimestamp() < time.time() - self.expireBefore: ! if options.verbose: print 'message %s has expired' % (msg.key()) self.removeMessage(msg) --- 269,273 ---- for msg in self: if msg.createTimestamp() < time.time() - self.expireBefore: ! if options["globals", "verbose"]: print 'message %s has expired' % (msg.key()) self.removeMessage(msg) Index: FileCorpus.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/FileCorpus.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** FileCorpus.py 29 Jan 2003 03:23:34 -0000 1.3 --- FileCorpus.py 4 May 2003 03:05:33 -0000 1.4 *************** *** 134,138 **** raise ValueError ! if options.verbose: print 'adding',message.key(),'to corpus' --- 134,138 ---- raise ValueError ! if options["globals", "verbose"]: print 'adding',message.key(),'to corpus' *************** *** 146,150 **** '''Remove a Message from this corpus''' ! if options.verbose: print 'removing',message.key(),'from corpus' --- 146,150 ---- '''Remove a Message from this corpus''' ! if options["globals", "verbose"]: print 'removing',message.key(),'from corpus' *************** *** 164,168 **** s = '' ! if options.verbose and nummsgs > 0: lst = ', ' + '%s' % (self.keys()) else: --- 164,168 ---- s = '' ! if options["globals", "verbose"] and nummsgs > 0: lst = ', ' + '%s' % (self.keys()) else: *************** *** 208,212 **** '''Read the Message substance from the file''' ! if options.verbose: print 'loading', self.file_name --- 208,212 ---- '''Read the Message substance from the file''' ! if options["globals", "verbose"]: print 'loading', self.file_name *************** *** 224,228 **** '''Write the Message substance to the file''' ! if options.verbose: print 'storing', self.file_name --- 224,228 ---- '''Write the Message substance to the file''' ! if options["globals", "verbose"]: print 'storing', self.file_name *************** *** 235,239 **** '''Message hara-kiri''' ! if options.verbose: print 'physically deleting file',self.pathname() --- 235,239 ---- '''Message hara-kiri''' ! if options["globals", "verbose"]: print 'physically deleting file',self.pathname() *************** *** 254,258 **** sub = self.getSubstance() ! if options.verbose: sub = self.getSubstance() else: --- 254,258 ---- sub = self.getSubstance() ! if options["globals", "verbose"]: sub = self.getSubstance() else: *************** *** 297,301 **** '''Read the Message substance from the file''' ! if options.verbose: print 'loading', self.file_name --- 297,301 ---- '''Read the Message substance from the file''' ! if options["globals", "verbose"]: print 'loading', self.file_name *************** *** 315,319 **** '''Write the Message substance to the file''' ! if options.verbose: print 'storing', self.file_name --- 315,319 ---- '''Write the Message substance to the file''' ! if options["globals", "verbose"]: print 'storing', self.file_name *************** *** 453,461 **** print 'Message %s spam probability is %f' % (msg.key(), prob) ! if prob < options.ham_cutoff: print 'Moving %s from unsurecorpus to hamcorpus, \ based on prob of %f' % (msg.key(), prob) hamcorpus.takeMessage(msg.key(), unsurecorpus) ! elif prob > options.spam_cutoff: print 'Moving %s from unsurecorpus to spamcorpus, \ based on prob of %f' % (msg.key(), prob) --- 453,461 ---- print 'Message %s spam probability is %f' % (msg.key(), prob) ! if prob < options["Categorization", "ham_cutoff"]: print 'Moving %s from unsurecorpus to hamcorpus, \ based on prob of %f' % (msg.key(), prob) hamcorpus.takeMessage(msg.key(), unsurecorpus) ! elif prob > options["Categorization", "spam_cutoff"]: print 'Moving %s from unsurecorpus to spamcorpus, \ based on prob of %f' % (msg.key(), prob) *************** *** 690,694 **** sys.exit() ! options.verbose = False runTestServer = False setupTestServer = False --- 690,694 ---- sys.exit() ! options["globals", "verbose"] = False runTestServer = False setupTestServer = False *************** *** 711,721 **** cleanupTestServer = True elif opt == '-v': ! options.verbose = True elif opt == '-g': useGzip = True elif opt == '-u': useExistingDB = True - elif opt == '-v': - options.verbose = True if setupTestServer: --- 711,719 ---- cleanupTestServer = True elif opt == '-v': ! options["globals", "verbose"] = True elif opt == '-g': useGzip = True elif opt == '-u': useExistingDB = True if setupTestServer: From anadelonbrin at users.sourceforge.net Sat May 3 21:10:38 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sat May 3 23:10:43 2003 Subject: [Spambayes-checkins] spambayes/contrib mod_spambayes.py,1.1,1.2 Message-ID: Update of /cvsroot/spambayes/spambayes/contrib In directory sc8-pr-cvs1:/tmp/cvs-serv10163/contrib Modified Files: mod_spambayes.py Log Message: Updated to use new options style. Index: mod_spambayes.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/contrib/mod_spambayes.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** mod_spambayes.py 2 Feb 2003 18:28:27 -0000 1.1 --- mod_spambayes.py 4 May 2003 03:10:36 -0000 1.2 *************** *** 12,16 **** from spambayes import hammie, Options, mboxutils ! dbf = os.path.expanduser(Options.options.hammiefilter_persistent_storage_file) class SpambayesFilter(BufferAllFilter): --- 12,16 ---- from spambayes import hammie, Options, mboxutils ! dbf = os.path.expanduser(Options.options["Storage", "persistent_storage_file"]) class SpambayesFilter(BufferAllFilter): *************** *** 21,25 **** prob = self.hammie.score("%s\r\n%s" % (self.serverheaders, s)) print "| prob: %.5f" % prob ! if prob >= Options.options.spam_cutoff: print self.serverheaders print "text:", s[0:40], "...", s[-40:] --- 21,25 ---- prob = self.hammie.score("%s\r\n%s" % (self.serverheaders, s)) print "| prob: %.5f" % prob ! if prob >= Options.options["Categorization", "spam_cutoff"]: print self.serverheaders print "text:", s[0:40], "...", s[-40:] From anadelonbrin at users.sourceforge.net Sat May 3 21:16:47 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sat May 3 23:16:50 2003 Subject: [Spambayes-checkins] spambayes/utilities HistToGNU.py, 1.2, 1.3 pop3graph.py, 1.2, 1.3 Message-ID: Update of /cvsroot/spambayes/spambayes/utilities In directory sc8-pr-cvs1:/tmp/cvs-serv11637/utilities Modified Files: HistToGNU.py pop3graph.py Log Message: Updated to use new options style. Index: HistToGNU.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/utilities/HistToGNU.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** HistToGNU.py 17 Jan 2003 06:42:53 -0000 1.2 --- HistToGNU.py 4 May 2003 03:16:45 -0000 1.3 *************** *** 72,79 **** usage(1, msg) ! if not args and options.save_histogram_pickles: args = [] for f in ('ham', 'spam'): ! fname = "%s_%shist.pik" % (options.pickle_basename, f) args.append(fname) --- 72,80 ---- usage(1, msg) ! if not args and options["TestDriver", "save_histogram_pickles"]: args = [] for f in ('ham', 'spam'): ! fname = "%s_%shist.pik" % (options["TestDriver", ! "pickle_basename"], f) args.append(fname) Index: pop3graph.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/utilities/pop3graph.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pop3graph.py 29 Jan 2003 03:23:35 -0000 1.2 --- pop3graph.py 4 May 2003 03:16:45 -0000 1.3 *************** *** 25,34 **** # Create the corpuses and the factory that reads the messages. ! if options.pop3proxy_cache_use_gzip: messageFactory = GzipFileMessageFactory() else: messageFactory = FileMessageFactory() ! spamCorpus = FileCorpus(messageFactory, options.pop3proxy_spam_cache) ! hamCorpus = FileCorpus(messageFactory, options.pop3proxy_ham_cache) # Read in all the trained messages. --- 25,36 ---- # Create the corpuses and the factory that reads the messages. ! if options["pop3proxy", "cache_use_gzip"]: messageFactory = GzipFileMessageFactory() else: messageFactory = FileMessageFactory() ! spamCorpus = FileCorpus(messageFactory, options["pop3proxy", ! "spam_cache"]) ! hamCorpus = FileCorpus(messageFactory, options["pop3proxy", ! "ham_cache"]) # Read in all the trained messages. *************** *** 55,59 **** for key in keys: message = allTrained[key] ! disposition = message[options.hammie_header_name] if (message._pop3CacheDisposition == disposition): successful += 1 --- 57,62 ---- for key in keys: message = allTrained[key] ! disposition = message[options["Headers", ! "classification_header_name"]] if (message._pop3CacheDisposition == disposition): successful += 1 From anadelonbrin at users.sourceforge.net Sat May 3 21:59:07 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sat May 3 23:59:13 2003 Subject: [Spambayes-checkins] spambayes/spambayes ProxyUI.py,1.6,1.7 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv23773/spambayes Modified Files: ProxyUI.py Log Message: Fix so that the correct state information will be displayed after entering in configuration details. Index: ProxyUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ProxyUI.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** ProxyUI.py 3 May 2003 22:16:30 -0000 1.6 --- ProxyUI.py 4 May 2003 03:59:05 -0000 1.7 *************** *** 462,466 **** # Recreate the state. ! self.state_recreator() def verifyInput(self, parms): --- 462,466 ---- # Recreate the state. ! state = self.state_recreator() def verifyInput(self, parms): From anadelonbrin at users.sourceforge.net Sat May 3 21:59:07 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sat May 3 23:59:14 2003 Subject: [Spambayes-checkins] spambayes pop3proxy.py,1.78,1.79 Message-ID: Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv23773 Modified Files: pop3proxy.py Log Message: Fix so that the correct state information will be displayed after entering in configuration details. Index: pop3proxy.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/pop3proxy.py,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -d -r1.78 -r1.79 *** pop3proxy.py 24 Apr 2003 07:43:44 -0000 1.78 --- pop3proxy.py 4 May 2003 03:59:05 -0000 1.79 *************** *** 661,664 **** --- 661,665 ---- del proxyListeners[:] _createProxies(state.servers, state.proxyPorts) + return state def main(servers, proxyPorts, uiPort, launchUI): From timstone4 at users.sourceforge.net Sun May 4 19:22:14 2003 From: timstone4 at users.sourceforge.net (Tim Stone) Date: Sun May 4 21:22:18 2003 Subject: [Spambayes-checkins] spambayes/spambayes FileCorpus.py,1.4,1.5 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv15797 Modified Files: FileCorpus.py Log Message: Corrected uncaught exception problem when a file in the cache mysteriously disappears from the filesystem. Index: FileCorpus.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/FileCorpus.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** FileCorpus.py 4 May 2003 03:05:33 -0000 1.4 --- FileCorpus.py 5 May 2003 01:22:11 -0000 1.5 *************** *** 276,281 **** '''Return the create timestamp for the file''' ! stats = os.stat(self.pathname()) ! ctime = stats[stat.ST_CTIME] return ctime --- 276,287 ---- '''Return the create timestamp for the file''' ! # make sure we don't die if someone has ! #removed the file out from underneath us ! try: ! stats = os.stat(self.pathname()) ! except OSError, e: ! ctime = time.time() ! else: ! ctime = stats[stat.ST_CTIME] return ctime From anadelonbrin at users.sourceforge.net Sun May 4 19:23:09 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sun May 4 21:23:13 2003 Subject: [Spambayes-checkins] spambayes pop3proxy.py,1.79,1.80 Message-ID: Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv15999 Modified Files: pop3proxy.py Log Message: Fix bug that could stop some messages in the cache directories being loaded into the cache. Index: pop3proxy.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/pop3proxy.py,v retrieving revision 1.79 retrieving revision 1.80 diff -C2 -d -r1.79 -r1.80 *** pop3proxy.py 4 May 2003 03:59:05 -0000 1.79 --- pop3proxy.py 5 May 2003 01:23:07 -0000 1.80 *************** *** 585,597 **** options["pop3proxy", "spam_cache"], ! '[0123456789]*', cacheSize=20) self.hamCorpus = ExpiryFileCorpus(age, factory, options["pop3proxy", "ham_cache"], ! '[0123456789]*', cacheSize=20) self.unknownCorpus = ExpiryFileCorpus(age, factory, options["pop3proxy", "unknown_cache"], ! '[0123456789]*', cacheSize=20) # Given that (hopefully) users will get to the stage --- 585,600 ---- options["pop3proxy", "spam_cache"], ! '[0123456789\-]*', ! cacheSize=20) self.hamCorpus = ExpiryFileCorpus(age, factory, options["pop3proxy", "ham_cache"], ! '[0123456789\-]*', ! cacheSize=20) self.unknownCorpus = ExpiryFileCorpus(age, factory, options["pop3proxy", "unknown_cache"], ! '[0123456789\-]*', ! cacheSize=20) # Given that (hopefully) users will get to the stage From anadelonbrin at users.sourceforge.net Tue May 6 16:59:03 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Tue May 6 18:59:08 2003 Subject: [Spambayes-checkins] spambayes/spambayes Options.py,1.49,1.50 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv15466/spambayes Modified Files: Options.py Log Message: Add backwards compatibility to allow renamed options to be accessed via the old getattr method. Index: Options.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Options.py,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -d -r1.49 -r1.50 *** Options.py 2 May 2003 04:17:06 -0000 1.49 --- Options.py 6 May 2003 22:59:00 -0000 1.50 *************** *** 75,82 **** except ImportError: import StringIO - try: - from sets import Set - except ImportError: - from compatsets import Set import re --- 75,78 ---- *************** *** 919,935 **** ), - "globals" : ( - ("verbose", "Verbose", False, - """""", - BOOLEAN, RESTORE), - - ("dbm_type", "Database storage type", "best", - """What DBM storage type should we use? Must be best, db3hash, dbhash, - gdbm, or dumbdbm. Windows folk should steer clear of dbhash. Default - is "best", which will pick the best DBM type available on your - platform.""", - ("best", "bd3hash", "dbhash", "gdbm", "dumbdbm"), RESTORE), - ), - "imap" : ( ("server", "Server", (), --- 915,918 ---- *************** *** 998,1001 **** --- 981,997 ---- IMAP_FOLDER, DO_NOT_RESTORE), ), + + "globals" : ( + ("verbose", "Verbose", False, + """""", + BOOLEAN, RESTORE), + + ("dbm_type", "Database storage type", "best", + """What DBM storage type should we use? Must be best, db3hash, dbhash, + gdbm, or dumbdbm. Windows folk should steer clear of dbhash. Default + is "best", which will pick the best DBM type available on your + platform.""", + ("best", "bd3hash", "dbhash", "gdbm", "dumbdbm"), RESTORE), + ), } *************** *** 1009,1013 **** self.allowed_values = allowed self.restore = restore ! self.value = None self.delimiter = None --- 1005,1009 ---- self.allowed_values = allowed self.restore = restore ! self.value = default self.delimiter = None *************** *** 1066,1070 **** def is_valid_single(self, value): '''Return True iff value is a valid value for this option. ! Use if multiple values are not allowed.''' if type(self.allowed_values) == types.TupleType: if value in self.allowed_values: --- 1062,1066 ---- def is_valid_single(self, value): '''Return True iff value is a valid value for this option. ! Use when multiple values are not allowed.''' if type(self.allowed_values) == types.TupleType: if value in self.allowed_values: *************** *** 1396,1399 **** --- 1392,1399 ---- # *** This will vanish soon, so do not make use of it in # new code *** + for (oldsect, oldopt), (newsect, newopt) in conversion_table.items(): + if (newsect, newopt) == (section, option): + section = oldsect + option = oldopt setattr(options, option, value) old_name = section[0:1].lower() + section[1:] + "_" + option From anadelonbrin at users.sourceforge.net Tue May 6 17:33:27 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Tue May 6 19:33:32 2003 Subject: [Spambayes-checkins] spambayes imapfilter.py,1.41,1.42 Message-ID: Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv27757 Modified Files: imapfilter.py Log Message: Delete any existing spambayes header before training. Update option names to new names/styles. Add storage option to allow specification of the messageinfo database, so that copies don't end up littering lots of CWDs. (Also provide access to this option in pop3proxy and imapfilter ui's). Index: imapfilter.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/imapfilter.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** imapfilter.py 29 Apr 2003 03:59:04 -0000 1.41 --- imapfilter.py 6 May 2003 23:33:22 -0000 1.42 *************** *** 239,242 **** --- 239,283 ---- return response + def folder_list(self): + '''Return a alphabetical list of all folders available on the + server''' + response = self.list() + if response[0] != "OK": + return [] + all_folders = response[1] + folders = [] + for fol in all_folders: + r = re.compile(r"\(([\w\\ ]*)\) ") + m = r.search(fol) + name_attributes = fol[:m.end()-1] + # IMAP is a truly odd protocol. The delimiter is + # only the delimiter for this particular folder - each + # folder *may* have a different delimiter + self.folder_delimiter = fol[m.end()+1:m.end()+2] + # a bit of a hack, but we really need to know if this is + # the case + if self.folder_delimiter == ',': + print """WARNING: Your imap server uses commas as the folder + delimiter. This may cause unpredictable errors.""" + folders.append(fol[m.end()+5:-1]) + folders.sort() + return folders + + def FindMessage(self, id): + '''A (potentially very expensive) method to find a message with + a given spambayes id (header), and return a message object (no + substance).''' + # If efficiency becomes a concern, what we could do is store a + # dict of key-to-folder, and look in that folder first. (It might + # have moved independantly of us, so we would still have to search + # if we didn't find it). For the moment, we do an search through + # all folders, alphabetically. + for folder_name in self.folder_list(): + fol = IMAPFolder(folder_name) + for msg in fol: + if msg.id == id: + return msg + return None + class IMAPMessage(message.SBHeaderMessage): def __init__(self): *************** *** 415,419 **** def __getitem__(self, key): ! '''Return message (no substance) matching the given uid.''' # We don't retrieve the substances of the message here - you need # to call msg.get_substance() to do that. --- 456,460 ---- def __getitem__(self, key): ! '''Return message (no substance) matching the given *uid*.''' # We don't retrieve the substances of the message here - you need # to call msg.get_substance() to do that. *************** *** 422,426 **** # that not all servers accept it, even though it is in the RFC response = imap.uid("FETCH", key, "RFC822.HEADER") ! self._check(response, "uid fetch header lines") data = _extract_fetch_data(response[1][0]) --- 463,467 ---- # that not all servers accept it, even though it is in the RFC response = imap.uid("FETCH", key, "RFC822.HEADER") ! self._check(response, "uid fetch header") data = _extract_fetch_data(response[1][0]) *************** *** 465,468 **** --- 506,510 ---- if msg.GetTrained() == (not isSpam): msg.get_substance() + msg.delSBHeaders() classifier.unlearn(msg.asTokens(), not isSpam) # Once the message has been untrained, it's training memory *************** *** 474,477 **** --- 516,520 ---- if msg.GetTrained() is None: msg.get_substance() + msg.delSBHeaders() classifier.learn(msg.asTokens(), isSpam) num_trained += 1 From anadelonbrin at users.sourceforge.net Tue May 6 17:33:27 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Tue May 6 19:33:32 2003 Subject: [Spambayes-checkins] spambayes/spambayes ImapUI.py, 1.9, 1.10 Options.py, 1.50, 1.51 ProxyUI.py, 1.7, 1.8 UserInterface.py, 1.8, 1.9 message.py, 1.25, 1.26 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv27757/spambayes Modified Files: ImapUI.py Options.py ProxyUI.py UserInterface.py message.py Log Message: Delete any existing spambayes header before training. Update option names to new names/styles. Add storage option to allow specification of the messageinfo database, so that copies don't end up littering lots of CWDs. (Also provide access to this option in pop3proxy and imapfilter ui's). Index: ImapUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ImapUI.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** ImapUI.py 3 May 2003 22:16:30 -0000 1.9 --- ImapUI.py 6 May 2003 23:33:24 -0000 1.10 *************** *** 89,92 **** --- 89,93 ---- ('Categorization', 'ham_cutoff'), ('Categorization', 'spam_cutoff'), + ('Storage', 'messageinfo_storage_file'), ) *************** *** 142,146 **** self._writePreamble("Select Filter Folders") self._login_to_imap() ! available_folders = self._folder_list() content = self.html.configForm.clone() content.configFormContent = "" --- 143,147 ---- self._writePreamble("Select Filter Folders") self._login_to_imap() ! available_folders = self.imap.folder_list() content = self.html.configForm.clone() content.configFormContent = "" *************** *** 191,195 **** self._writePreamble("Select Training Folders") self._login_to_imap() ! available_folders = self._folder_list() content = self.html.configForm.clone() content.configFormContent = "" --- 192,196 ---- self._writePreamble("Select Training Folders") self._login_to_imap() ! available_folders = self.imap.folder_list() content = self.html.configForm.clone() content.configFormContent = "" *************** *** 259,285 **** return self._buildBox(options.display_name(section, option), None, folderTable) - - def _folder_list(self): - '''Return a alphabetical list of all folders available - on the server''' - response = self.imap.list() - if response[0] != "OK": - return [] - all_folders = response[1] - folders = [] - for fol in all_folders: - r = re.compile(r"\(([\w\\ ]*)\) ") - m = r.search(fol) - name_attributes = fol[:m.end()-1] - # IMAP is a truly odd protocol. The delimiter is - # only the delimiter for this particular folder - each - # folder *may* have a different delimiter - self.folder_delimiter = fol[m.end()+1:m.end()+2] - # a bit of a hack, but we really need to know if this is - # the case - if self.folder_delimiter == ',': - print """WARNING: Your imap server uses commas as the folder - delimiter. This may cause unpredictable errors.""" - folders.append(fol[m.end()+5:-1]) - folders.sort() - return folders --- 260,261 ---- Index: Options.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Options.py,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** Options.py 6 May 2003 22:59:00 -0000 1.50 --- Options.py 6 May 2003 23:33:24 -0000 1.51 *************** *** 614,617 **** --- 614,627 ---- directory.""", FILE_WITH_PATH, DO_NOT_RESTORE), + + ("messageinfo_storage_file", "Message information file name", "spambayes.messageinfo.db", + """Spambayes builds a database of information about messages + that it has already seen and trained or classified. This + database is used to ensure that these messages are retrained + or reclassified (unless specifically requested to). This option + specifies the name of the database file. If you don't give a + full pathname, the name will be taken to be relative to the current + working directory.""", + FILE_WITH_PATH, DO_NOT_RESTORE), ), Index: ProxyUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ProxyUI.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** ProxyUI.py 4 May 2003 03:59:05 -0000 1.7 --- ProxyUI.py 6 May 2003 23:33:24 -0000 1.8 *************** *** 101,104 **** --- 101,105 ---- ('Categorization', 'ham_cutoff'), ('Categorization', 'spam_cutoff'), + ('Storage', 'messageinfo_storage_file'), ) *************** *** 340,346 **** if len(keys) == 0: keys, date, prior, this, next = self._buildReviewKeys(start) ! keyedMessageInfo = {options.header_spam_string: [], ! options.header_ham_string: [], ! options.header_unsure_string: []} for key in keys: # Parse the message, get the judgement header and build a message --- 341,347 ---- if len(keys) == 0: keys, date, prior, this, next = self._buildReviewKeys(start) ! keyedMessageInfo = {options["Headers", "header_spam_string"]: [], ! options["Headers", "header_ham_string"]: [], ! options["Headers", "header_unsure_string"]: []} for key in keys: # Parse the message, get the judgement header and build a message *************** *** 348,354 **** cachedMessage = sourceCorpus[key] message = spambayes.mboxutils.get_message(cachedMessage.getSubstance()) ! judgement = message[options.hammie_header_name] if judgement is None: ! judgement = options.header_unsure_string else: judgement = judgement.split(';')[0].strip() --- 349,356 ---- cachedMessage = sourceCorpus[key] message = spambayes.mboxutils.get_message(cachedMessage.getSubstance()) ! judgement = message[options["Headers", ! "classification_header_name"]] if judgement is None: ! judgement = options["Headers", "header_unsure_string"] else: judgement = judgement.split(';')[0].strip() *************** *** 368,374 **** templateRow = page.reviewRow.clone() page.table = "" # To make way for the real rows. ! for header, label in ((options.header_spam_string, 'Spam'), ! (options.header_ham_string, 'Ham'), ! (options.header_unsure_string, 'Unsure')): messages = keyedMessageInfo[header] if messages: --- 370,380 ---- templateRow = page.reviewRow.clone() page.table = "" # To make way for the real rows. ! for header, label in ((options["Headers", ! "header_spam_string"], 'Spam'), ! (options["Headers", ! "header_ham_string"], 'Ham'), ! (options["Headers", ! "header_unsure_string"], ! 'Unsure')): messages = keyedMessageInfo[header] if messages: Index: UserInterface.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/UserInterface.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** UserInterface.py 28 Apr 2003 23:36:24 -0000 1.8 --- UserInterface.py 6 May 2003 23:33:24 -0000 1.9 *************** *** 98,102 **** def onIncomingConnection(self, clientSocket): """Checks the security settings.""" ! return options.html_ui_allow_remote_connections or \ clientSocket.getpeername()[0] == clientSocket.getsockname()[0] --- 98,102 ---- def onIncomingConnection(self, clientSocket): """Checks the security settings.""" ! return options["html_ui", "allow_remote_connections"] or \ clientSocket.getpeername()[0] == clientSocket.getsockname()[0] Index: message.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/message.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** message.py 29 Apr 2003 13:46:18 -0000 1.25 --- message.py 6 May 2003 23:33:24 -0000 1.26 *************** *** 89,92 **** --- 89,93 ---- import sys + import os import types import re *************** *** 128,133 **** del self.db[msg.getId()] ! # this should come from a Mark Hammond idea of a master db ! msginfoDB = MessageInfoDB("spambayes.messageinfo.db") class Message(email.Message.Message): --- 129,139 ---- del self.db[msg.getId()] ! # This should come from a Mark Hammond idea of a master db ! # For the moment, we get the name of another file from the options, ! # so that these files don't litter lots of working directories. ! # Once there is a master db, this option can be removed. ! message_info_db_name = options["Storage", "messageinfo_storage_file"] ! message_info_db_name = os.path.expanduser(message_info_db_name) ! msginfoDB = MessageInfoDB(message_info_db_name) class Message(email.Message.Message): From anadelonbrin at users.sourceforge.net Tue May 6 17:45:27 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Tue May 6 19:45:31 2003 Subject: [Spambayes-checkins] spambayes/spambayes Options.py,1.51,1.52 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv31490/spambayes Modified Files: Options.py Log Message: Fix for [ 733247 ] crash when using merged-in options. Index: Options.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Options.py,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** Options.py 6 May 2003 23:33:24 -0000 1.51 --- Options.py 6 May 2003 23:45:24 -0000 1.52 *************** *** 1436,1441 **** if self.multiple_values_allowed(section, option): value = self.convert(section, option, value) ! self.set(section, option, self.convert(section, option, ! value)) # backward compatibility guff self._oldset(sect, opt, value) --- 1436,1441 ---- if self.multiple_values_allowed(section, option): value = self.convert(section, option, value) ! value = self.convert(section, option, value) ! self.set(section, option, value) # backward compatibility guff self._oldset(sect, opt, value) From anadelonbrin at users.sourceforge.net Sun May 11 16:46:37 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sun May 11 18:46:41 2003 Subject: [Spambayes-checkins] spambayes/spambayes message.py,1.26,1.27 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv1673/spambayes Modified Files: message.py Log Message: Incorrectly placed ']', causing KeyError when deleting spambayes headers. Index: message.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/message.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** message.py 6 May 2003 23:33:24 -0000 1.26 --- message.py 11 May 2003 22:46:35 -0000 1.27 *************** *** 305,309 **** del self[options['Hammie','header_name']] del self[options['pop3proxy','mailid_header_name']] ! del self[options['Hammie','header_name' + "-ID"]] # test mode header del self[options['pop3proxy','prob_header_name']] del self[options['pop3proxy','thermostat_header_name']] --- 305,309 ---- del self[options['Hammie','header_name']] del self[options['pop3proxy','mailid_header_name']] ! del self[options['Hammie','header_name'] + "-ID"] # test mode header del self[options['pop3proxy','prob_header_name']] del self[options['pop3proxy','thermostat_header_name']] From anadelonbrin at users.sourceforge.net Sun May 11 16:49:44 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sun May 11 18:49:47 2003 Subject: [Spambayes-checkins] spambayes imapfilter.py,1.42,1.43 Message-ID: Update of /cvsroot/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv2419 Modified Files: imapfilter.py Log Message: Add SSL support to imapfilter, if the imaplib has the IMAP_SSL class (Python 2.3b1 has this, 2.2.2 does not). THIS IS UNTESTED, but should work (for the most part, it's just passing a different class to inherit from). I don't have 2.3, so can't test it yet. Please let me know if there are problems with it. (I have tested that normal, non-SSL filtering still works). Index: imapfilter.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/imapfilter.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** imapfilter.py 6 May 2003 23:33:22 -0000 1.42 --- imapfilter.py 11 May 2003 22:49:41 -0000 1.43 *************** *** 57,75 **** To Do: - o Find a better way to remove old msg from info database when saving - modified messages o IMAPMessage and IMAPFolder currently carry out very simple checks of responses received from IMAP commands, but if the response is not "OK", then the filter terminates. Handling of these errors could be much nicer. ! o IMAP over SSL would be nice. imaplib in Python 2.3 has an SSL class ! that we could inherit from. This idea would be that SSL is available ! if the SSL class is available (so those using Python 2.2 can't use ! imapfilter with SSL, but 2.3ers can). It's easy enough to do the ! enabling/disabling of the options (don't forget to wipe it from the ! UI list), but I'm not quite sure how to handle the inheritance. We ! don't actually use the IMAP4 class, we use our own class that inherits ! from that. How can we dynamically select which class to inherit from? ! (This is probably where my lack of Python expertise shows up...) o Develop a test script, like testtools/pop3proxytest.py that runs through some tests (perhaps with a *real* imap server, rather than --- 57,65 ---- To Do: o IMAPMessage and IMAPFolder currently carry out very simple checks of responses received from IMAP commands, but if the response is not "OK", then the filter terminates. Handling of these errors could be much nicer. ! o IMAP over SSL is untested. o Develop a test script, like testtools/pop3proxytest.py that runs through some tests (perhaps with a *real* imap server, rather than *************** *** 102,106 **** import socket - import imaplib import os import re --- 92,95 ---- *************** *** 119,122 **** --- 108,121 ---- from spambayes.ImapUI import IMAPUserInterface + from imaplib import Debug + from imaplib import Time2Internaldate + try: + if options["imap", "use_ssl"]: + from imaplib import IMAP_SSL as BaseIMAP + else: + from imaplib import IMAP4 as BaseIMAP + except ImportError: + from imaplib import IMAP4 as BaseIMAP + # global IMAPlib object global imap *************** *** 181,191 **** return data ! class IMAPSession(imaplib.IMAP4): '''A class extending the IMAP4 class, with a few optimizations''' def __init__(self, server, port, debug=0, do_expunge=False): ! imaplib.Debug = debug # this is a global in the imaplib module try: ! imaplib.IMAP4.__init__(self, server, port) except: # A more specific except would be good here, but I get --- 180,190 ---- return data ! class IMAPSession(BaseIMAP): '''A class extending the IMAP4 class, with a few optimizations''' def __init__(self, server, port, debug=0, do_expunge=False): ! Debug = debug # this is a global in the imaplib module try: ! BaseIMAP.__init__(self, server, port) except: # A more specific except would be good here, but I get *************** *** 204,209 **** def login(self, username, pwd): try: ! imaplib.IMAP4.login(self, username, pwd) # superclass login ! except imaplib.IMAP4.error, e: if str(e) == "permission denied": print "There was an error logging in to the IMAP server." --- 203,208 ---- def login(self, username, pwd): try: ! BaseIMAP.login(self, username, pwd) # superclass login ! except BaseIMAP.error, e: if str(e) == "permission denied": print "There was an error logging in to the IMAP server." *************** *** 217,221 **** if self.do_expunge: self.expunge() ! imaplib.IMAP4.logout(self) # superclass logout def SelectFolder(self, folder): --- 216,220 ---- if self.do_expunge: self.expunge() ! BaseIMAP.logout(self) # superclass logout def SelectFolder(self, folder): *************** *** 304,310 **** parsed_date = parsedate(message_date) if parsed_date is not None: ! return imaplib.Time2Internaldate(time.mktime(parsed_date)) else: ! return imaplib.Time2Internaldate(time.time()) def get_substance(self): --- 303,309 ---- parsed_date = parsedate(message_date) if parsed_date is not None: ! return Time2Internaldate(time.mktime(parsed_date)) else: ! return Time2Internaldate(time.time()) def get_substance(self): From anadelonbrin at users.sourceforge.net Sun May 11 16:49:44 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Sun May 11 18:49:48 2003 Subject: [Spambayes-checkins] spambayes/spambayes ImapUI.py,1.10,1.11 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv2419/spambayes Modified Files: ImapUI.py Log Message: Add SSL support to imapfilter, if the imaplib has the IMAP_SSL class (Python 2.3b1 has this, 2.2.2 does not). THIS IS UNTESTED, but should work (for the most part, it's just passing a different class to inherit from). I don't have 2.3, so can't test it yet. Please let me know if there are problems with it. (I have tested that normal, non-SSL filtering still works). Index: ImapUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ImapUI.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** ImapUI.py 6 May 2003 23:33:24 -0000 1.10 --- ImapUI.py 11 May 2003 22:49:42 -0000 1.11 *************** *** 21,36 **** To do: - o There is a function to get a list of all the folders available on - the server, but nothing is done with this. Obviously what we would - like is to present a page where the user selects (checkboxes) the - folders that s/he wishes to filter, the folders s/he wishes to use - as train-as-ham and train-as-spam, and (radio buttons) the folders - to move suspected spam and unsures into. I think this should be - a separate page from the standard config as it's already going to - be really big if there are lots of folders to choose from. - An alternative design would be to have a single list of the folders - and five columns - three of checkboxes (filter, train-as-spam and - train-as-ham) and two of radio buttons (spam folder and ham folder). - I think this might be more confusing, though. o This could have a neat review page, like pop3proxy, built up by asking the IMAP server appropriate questions. I don't know whether --- 21,24 ---- *************** *** 96,99 **** --- 84,94 ---- def __init__(self, cls, imap, pwd): global classifier + # Only offer SSL if it is available + try: + from imaplib import IMAP_SSL + except ImportError: + parm_list = list(parm_map) + parm_list.remove(("imap", "use_ssl")) + parm_map = tuple(parm_list) UserInterface.UserInterface.__init__(self, cls, parm_map) classifier = cls From anadelonbrin at users.sourceforge.net Mon May 12 17:26:37 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Mon May 12 19:26:40 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000 msgstore.py,1.41,1.42 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000 In directory sc8-pr-cvs1:/tmp/cvs-serv32351/Outlook2000 Modified Files: msgstore.py Log Message: An additional patch necessary for users with locales with a decimal separator other than a period. ([ spambayes-Bugs-725466 ] Include a proper locale fix in Options.py discusses this further, although this is (probably) not a final solution for this problem. Index: msgstore.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/msgstore.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** msgstore.py 7 Mar 2003 06:29:12 -0000 1.41 --- msgstore.py 12 May 2003 23:26:35 -0000 1.42 *************** *** 2,5 **** --- 2,6 ---- import sys, os, re + import locale try: *************** *** 113,116 **** --- 114,121 ---- mapi.MAPI_USE_DEFAULT) self.session = mapi.MAPILogonEx(0, None, None, logonFlags) + # Set our locale to be English, so our plugin works OK + # ([ spambayes-Bugs-725466 ] Include a proper locale fix in Options.py + # has discussion about this problem.) + locale.setlocale(locale.LC_NUMERIC, "en") self.mapi_msg_stores = {} self.default_store_bin_eid = None From anadelonbrin at users.sourceforge.net Tue May 13 18:18:22 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Tue May 13 20:18:28 2003 Subject: [Spambayes-checkins] spambayes/spambayes Options.py, 1.52, 1.53 ProxyUI.py, 1.8, 1.9 UserInterface.py, 1.9, 1.10 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv2908/spambayes Modified Files: Options.py ProxyUI.py UserInterface.py Log Message: Add a refresh button to the review messages page in the pop3proxy web interface. Add a "check again" link in the "there are no more untrained messages" page in the pop3proxy web interface. Fix a bug in UserInterface.py that meant that options in sections with an underscore in the name (like html_ui) could not be set via the user interface (note that this is really only a patch, as it will still fail if there is more than one underscore in the section name, but let's just not do that, ok? ) Add an option "html_ui":"display_to" that, if True, will display the To header (along with from, subject and the classification) in the pop3proxy review messages web interface. This is an option since it makes the page wider than would fix on small resolutions, and is probably of limited use for those with only one mail account. Index: Options.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/Options.py,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** Options.py 6 May 2003 23:45:24 -0000 1.52 --- Options.py 14 May 2003 00:18:19 -0000 1.53 *************** *** 889,892 **** --- 889,901 ---- """""", BOOLEAN, RESTORE), + + ("display_to", "Display To: in message review", False, + """When reviewing messages via the web user interface, you are + presented with the message subject, the address the message is + from, and its classification. If you set this option, you will + also be shown the address the message was to. This might be + useful if you receive mail from multiple accounts, or if you + want to quickly identify mail received via a mailing list.""", + BOOLEAN, RESTORE), ), Index: ProxyUI.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/ProxyUI.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** ProxyUI.py 6 May 2003 23:33:24 -0000 1.8 --- ProxyUI.py 14 May 2003 00:18:19 -0000 1.9 *************** *** 84,87 **** --- 84,88 ---- ('pop3proxy', 'listen_ports'), ('pop3proxy', 'cache_messages'), + ('html_ui', 'display_to'), ('Header Options', None), ('pop3proxy', 'notate_to'), *************** *** 211,214 **** --- 212,217 ---- """Appends the rows of a table of messages to 'table'.""" stripe = 0 + if not options["html_ui", "display_to"]: + del table.to_header for key, messageInfo in keyedMessageInfo: row = self.html.reviewRow.clone() *************** *** 223,226 **** --- 226,233 ---- row.subject.href="view?key=%s&corpus=%s" % (key, label) row.from_ = messageInfo.fromHeader + if options["html_ui", "display_to"]: + row.to_ = messageInfo.toHeader + else: + del row.to_ subj = cgi.escape(messageInfo.subjectHeader) row.classify.href="showclues?key=%s&subject=%s" % (key, subj) *************** *** 237,273 **** numTrained = 0 numDeferred = 0 ! for key, value in params.items(): ! if key.startswith('classify:'): ! id = key.split(':')[2] ! if value == 'spam': ! targetCorpus = state.spamCorpus ! elif value == 'ham': ! targetCorpus = state.hamCorpus ! elif value == 'discard': ! targetCorpus = None ! try: ! state.unknownCorpus.removeMessage(state.unknownCorpus[id]) ! except KeyError: ! pass # Must be a reload. ! else: # defer ! targetCorpus = None ! numDeferred += 1 ! if targetCorpus: ! sourceCorpus = None ! if state.unknownCorpus.get(id) is not None: ! sourceCorpus = state.unknownCorpus ! elif state.hamCorpus.get(id) is not None: ! sourceCorpus = state.hamCorpus ! elif state.spamCorpus.get(id) is not None: ! sourceCorpus = state.spamCorpus ! if sourceCorpus is not None: try: ! targetCorpus.takeMessage(id, sourceCorpus) ! if numTrained == 0: ! self.write("

    Training... ") ! self.flush() ! numTrained += 1 except KeyError: pass # Must be a reload. # Report on any training, and save the database if there was any. --- 244,282 ---- numTrained = 0 numDeferred = 0 ! if params.get('go') != 'refresh': ! for key, value in params.items(): ! if key.startswith('classify:'): ! id = key.split(':')[2] ! if value == 'spam': ! targetCorpus = state.spamCorpus ! elif value == 'ham': ! targetCorpus = state.hamCorpus ! elif value == 'discard': ! targetCorpus = None try: ! state.unknownCorpus.removeMessage(\ ! state.unknownCorpus[id]) except KeyError: pass # Must be a reload. + else: # defer + targetCorpus = None + numDeferred += 1 + if targetCorpus: + sourceCorpus = None + if state.unknownCorpus.get(id) is not None: + sourceCorpus = state.unknownCorpus + elif state.hamCorpus.get(id) is not None: + sourceCorpus = state.hamCorpus + elif state.spamCorpus.get(id) is not None: + sourceCorpus = state.spamCorpus + if sourceCorpus is not None: + try: + targetCorpus.takeMessage(id, sourceCorpus) + if numTrained == 0: + self.write("

    Training... ") + self.flush() + numTrained += 1 + except KeyError: + pass # Must be a reload. # Report on any training, and save the database if there was any. *************** *** 391,395 **** else: page = "

    There are no untrained messages to display. " ! page += "Return Home.

    " title = "No untrained messages" box = self._buildBox(title, 'status.gif', page) --- 400,405 ---- else: page = "

    There are no untrained messages to display. " ! page += "Return Home, or " ! page += "check again.

    " title = "No untrained messages" box = self._buildBox(title, 'status.gif', page) *************** *** 428,431 **** --- 438,442 ---- subjectHeader = message["Subject"] or "(none)" fromHeader = message["From"] or "(none)" + toHeader = message["To"] or "(none)" try: part = typed_subpart_iterator(message, 'text', 'plain').next() *************** *** 453,456 **** --- 464,468 ---- messageInfo.subjectHeader = self._trimHeader(subjectHeader, 50, True) messageInfo.fromHeader = self._trimHeader(fromHeader, 40, True) + messageInfo.toHeader = self._trimHeader(toHeader, 40, True) messageInfo.bodySummary = self._trimHeader(text, 200) return messageInfo Index: UserInterface.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/UserInterface.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** UserInterface.py 6 May 2003 23:33:24 -0000 1.9 --- UserInterface.py 14 May 2003 00:18:19 -0000 1.10 *************** *** 508,511 **** --- 508,517 ---- if (sect, opt) in self.parm_ini_map: options.set(sect, opt, value) + # If a section name has an underscore in it (like html_ui) + # the split won't work the first time + else: + sect2, opt = opt.split('_', 1) + sect += '_' + sect2 + options.set(sect, opt, value) options.update_file(optionsPathname) From anadelonbrin at users.sourceforge.net Tue May 13 18:18:22 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Tue May 13 20:18:30 2003 Subject: [Spambayes-checkins] spambayes/spambayes/resources ui.html, 1.12, 1.13 ui_html.py, 1.12, 1.13 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes/resources In directory sc8-pr-cvs1:/tmp/cvs-serv2908/spambayes/resources Modified Files: ui.html ui_html.py Log Message: Add a refresh button to the review messages page in the pop3proxy web interface. Add a "check again" link in the "there are no more untrained messages" page in the pop3proxy web interface. Fix a bug in UserInterface.py that meant that options in sections with an underscore in the name (like html_ui) could not be set via the user interface (note that this is really only a patch, as it will still fail if there is more than one underscore in the section name, but let's just not do that, ok? ) Add an option "html_ui":"display_to" that, if True, will display the To header (along with from, subject and the classification) in the pop3proxy review messages web interface. This is an option since it makes the page wider than would fix on small resolutions, and is probably of limited use for those with only one mail account. Index: ui.html =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/resources/ui.html,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** ui.html 22 Apr 2003 02:25:04 -0000 1.12 --- ui.html 14 May 2003 00:18:19 -0000 1.13 *************** *** 173,176 **** --- 173,178 ----   +     *************** *** 205,208 **** --- 207,211 ---- Messages classified as TYPE: From: + To: Discard / *************** *** 219,222 **** --- 222,226 ---- Richie Hindle <richie@entrian.com> + Spambayes List <spambayes@python.org>       
    ! --- 238,242 ----     
    ! Index: ui_html.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/resources/ui_html.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** ui_html.py 22 Apr 2003 02:25:04 -0000 1.12 --- ui_html.py 14 May 2003 00:18:19 -0000 1.13 *************** *** 5,83 **** import zlib ! data = zlib.decompress("xÚÝ[{o\0339’ÿ€ù\016œ^$mcmI¶“ܬ,56±=ëÅ%\023Ÿ­¹Å`00(5%qÝÝìí‡e]°ßýªŠd7û\ ! aYÙÝÙ\003Î\011,u“,\026‹õøU‘ž|wùùböóÍ\025»ž}úÈn~úðñÏ\027Ì;\036\016ÿrv1\034^Î.uÛÁè„Í2\ ! žä²*áÑpxõ£\027|ûÍd]Ä\021}\012\036âg!‹H0\031N=úæ\005w)ç|+röS.2öç¤\020Ù’/ÄdH\035pL,\012\ ! ÎÖE‘\036‹¿•òqêÝd|\025s-\024ôNŠ©—¨ã\005_¬…dž½\003®žR™‰Ü\031q|búæÅ–f™«p˾°%t\030³?\ ! Œ^1žI\036\035±|#óüˆ­Eô(\012¹àç,æÙJ&c6bÿö›‚Ïa={ŒÃÎK•ÅзAàÛoø8’É\003¼_¨He\ ! cö»\021ü,¨‘\037%ˆT„Ï´®Õ#Ȭn{7z3Z.±m`Vʸaîx#äj\015<ÎU\024RG)64s§K\002|òHs7\ ! ˜ó$¡Iæ|ñ°ÊT™„0Ób$`¦s–ò0”Éjú¶úz\034‰%Ð8y{þí7¬ú™«,\024Ùq¡RhJŸX®\"\031²y\004\ ! 4ûúÍUQ¨¸Ó•øFU\"†ˆç\\þ€~gg¯\032Ë®¥|ò–\032b‘ç|%ô~\025(Ð\026¿â©^B¦å\000ïhl.\026¨Öv\ ! ¯5.s¿û~„ÿÎÙF†Å\032ôàí+w r\014d[2\\.—\\ŒÎ{øp\005ò¢`ìÜ}ƒú7Þpe4ÞL\017$Gé“ÙóL\ !  rhAç¬WAG¤‚žýúj:×\032·ƒ¢Ói\0271\\G‘ÉTÜ«DïgC?Å\002ÿ™Ž¥¼\0067tݧ7§£Wç\025õï‰ú\ ! y¿Ø&Cë*&CãÍà+\011\021Ý\031~ñè\035\012~\022ÊG¶ˆxžO}m@~`Zò”'4\002\\\0038*/˜ÈxÅòl1õõ›ÁJ.\ ! }Æ#¹J¦>Ÿç±\014ÃHøÃàu2ÏÓsà\003(4¨™‰ô.؉š“¥™\012ËEñ#\033>÷/bîº\\¢eh\031.øêˆä=\027°@œ”Ýl‹58\021Ã\035Ð5R\037L\ ! †©«Pï‘*ì\032Óˆ8Y«æw£²\007\012ö°«R÷\012e1WO\020\020Šµ&\000/Û¼\000\011ýÊЄ\001¦ÉØàD&iY9Ô]\ ! Z\017\ ! N=õO\001CÑÔŒ\034\021‚\025\001\016E_‚\"\\À¼>Z\004ÁBÈ£ü\026}\004 ¾N@€ôÈ…Úü\000eZb¾Æ›yÁ‹2×xÓ\ ! \014|3ò!Œ!ò¥ï\026t:\030\017ùt\036Í¢a\005-°ÖàË\031A°\014ƒ$s\004\017VðIåE?æÊ-’\002í©é€ñç0\035H\017,\011M\ ! Áê¤bõ\030°æfoGuujõ\004\035uðNz±\"º\000þ¨ Ô…e\032A|Ä…Y,2°.Èn üB]1k6¨}ž\015ÛÀw\017Í\ ! Õ;ÔP[­›(sÝ8ÃgÏä‡S\017\\¨«¢öÙæéðÜT°^ø®){Ïe\022OÛKH¤eÔèqóùæŒQ#â§\004=\011Èh\ ! 2\017ZCo vçwä<½àääddä1\031΃#w{¡/93Õ$BX6«(˜(\002‰ì\020\0328œ×’ÇŸ÷ ”Bs\013–€¤\ ! h7óqË^Ü99\015º\023€J¡§\027¸<\017Z\023t)koëÑ»¦)TÁ£ýfidO„‘cÜ\020­Er)1lí9kRƘ5´&\ ! dð->Ú=ìº;jýâ Ÿ’¼ÌDkXI/Û‹œ¡<˜Ð+ƒ †éSk%Èù¸5\007rÞ¤ß\034sÝ\035²nØ%nÇ\005¢û\ ! 3H×”~Þ‰'ß8M÷wkŒëÇÝiªR\000(ÐR®v¹f[!À²‘?ì5UM¤ÌH\015?b\002ïtëòØýý3ä\012\013,0\030\ ! B\002³‡¬N2[RÚ‡d¾Í\013\021ƒ‡7@¥¥,Ü”\030ôŒ~pá.\020\032–\034\006qåë\004ÑÊ\023¿èiu!k\006¸³\011\\H\ ! u£•à¬Q\003Ðn//TVe±‘êŠ#\004»\002ÌPä†i+SÒgêXÙ,àGžƒåbEk­òš„\036Yɬ\026“fÌ\017né³\ ! ê2\"aU±iO¤d\026ŠBëÇJº\003Iµ\012$Xj€ªk\032ÆX1=ßš•B4G/^-Ø”\027ªUCÀ¾X‹Å\003-§ L\ ! È\"07—E\001²X\002°\026X\002 âGU]\001\013_\022†ù3¤ìCF\017\020\023ˆù—b)2\037Ò]þhÊ;F0z(Fú#S60^\005E\ ! Žé0ñBDkD¡\007]Ê|Á³\015\031Q‡Op#ð\033•€Ùú'Ð\\ÐJjŒ¬Gë•ä\032|pÔ\007ÂF\026º¬T\023.ÓA\001§.Õ\ ! \036Ã\032@)\000Àýéjæø\014S\" ´É_Ë0\004¸Ã°ô6õAŠ\012Ä€ Ï|Õ\011•?rýÅ\016\002\011(¼\036¯¿õ\016×xÄÀ\017hk\ ! À\015ûÜEÌ\016\002ip—óX\026–ƒ•røÿ@Bôû\012Ýøc¸»Ay©\022\0229\016x8”9ò\007$Nœ\012j\003öh—¼\017\027(…ý˜\ ! ø\021z~-\003ÏyÌ6âîBLL¾³¸7kË]d2µË´zøWþÈõ[?\030\016'ßýrqù~öþ\027“¢–‰ÖL•hŸp€\ ! #é8\013’Ö™2¥/5?rÉ\016 ß/c€×\003ä#g¯_³æ›A$’\025dsÁ”\036ÖC¿4¥HZ?m\015ýåä×óN7v \ ! ¡ãèœI6¡af\002xñûß\0376»énU\016\030žJá@\004Gÿ\"\035àN\017¨áÀ\037û‡=Ç)¸Ðj¤]ÑtÊÎp½U\003ð‹\ ! /Qjð¾_M윦È2­¤;(ÔGµ\021Ù\005„ƒÃÃîè/»\011’ó\001o\006óg¥èYÃß›¯œGóÕ|\014‡¿þZ§+¤,\ ! {z§›Ïw3?hç*¾Ížujè\036Æíë0À[8\021讜ۘÕHF\001¸\005ŸlàuÀ0Ï\031žc\011ÛuRX\034õC¦âgš\ ! -ÛÃ.p\016j“ñ\024\015\033Ç÷\003\031¯¶¶qmS>òâ\037A¤ÒQ\005ôÍ\013ÌwŠÝÃŒ\032Å=¢…ßþ\011J\020Ûˆ\016|þ\023T0\ ! 6\022\031üÒ<*Òš5\017z\013\013Í2ˆ³ë·jS—\027ìéŸß¿Yö\034Ñïî\014¥‘%•ûÍ‘–‡½½ k0·bìà<<7ÐU_\ ! –©ÅÃwŒ}|Ø:\003ë¯`éïÞ\013nåb-\005»–I\010†õÐŒÞü\021ü\035`ž\004ÓX]åìP1pUŒÌïÔe:¡\ ! <ã¡T6‚\031KØŽÉ\010þóêçþ\000†œ†Z\015mõÕ7ÏUðêþþ-˜@ýõêxJÏÿ^\0260%tC:<ÿ{\031 4Öa\000Ÿ\ ! ›‰^\037ÓÊmg±Ú]=\007wxfµ\000z”#춹yÄ“\0074¹ †'ºÊµû±K‰Pö\036”öÐøVÊÙ‘¶EnFh:5\030\ ! ¾ìgž\007T_S¯+ÓHñ°‹åQ\010ºÍ«\"'\011¥±ý\030Ê\004 1ZR\\F…LyV\020WÇ!/¸ujW’Šøš4ã6Ïq\022\ ! 6•ÝÇxÄ\022\000jŠ©ÎL«¡3ƒæ)£ž\014ß[eÕß$AˆŽì?gt\020\"(}Ù¬UTåX€Í\022P0:J0¡òR®±\ ! [\003E$\012ù\"73\025”_dj\003ŽûL—ȧ>ž(¾˜žîìι¨Þï{m,}à}³\006\017ÛÔ\007D\003w®5ué­¿’ÜõN\ ! jµ=¾LòÂô­ÉYe¬Òí\003¬>˜='õZáÁn‰¥\003\004Çs…\007'È\031\035ç$¡\005BTO=vª.2qÓíºbÎ2\021«G\ ! º‡P\035†\037î]DØ@.ø_¥È¶ývP5צ€¯þ†¯ü®\010±Í³’‚ïµB:I¯O\020ý³Q{\027ú½\002 LÐWs¢g\ ! ðÃ>‘¿¸Ú%Ärƒ8û×ëtðöƒÍõâq¬WYc²{ñ'û-þ\012Ý)UEdh\017\\¬íâQ'Nó\010\002%xWð\"ï\ ! ¯\034UÍ\026fýXÆs`\0048@ã­jW­Ò,¶-T‰—~NNÏž©ˆ×¤ÖÏSZW„Þ¼}÷\014¡›LÍù\\B.·Õ…šÚ¥\ ! .ô\021¿.Á\031…Ás,dÐ:Ò6ã`[s/\030\015þãû?<3á×\004\027kÅ·\"‡ˆðŒ˜[œ\"\035UªÒz(\036{,cß!³\ ! $fLƒÒ K\034€ƒsPŠ?äŒt¢\007ò§\036l¥ÌÚ\021‹äƒÐ\002›£Nƒ³dձߡ{Õ¬>×\"\0323·ÄXwÊê\036„'\ ! ºèÉ\"nìãÙâ|ûb'D–+s\007÷±[iê\023Pg€\003&ú\000…{~\006·¢(³¤®ã6oÔáM\002»à¿é ~Ü\ ! ¿\037ºÓ{ÝÇÓ‘ÁF\020\023\033ì^\034ö_¿ÛGñ¨\010ÿ\003P{FçªöJÝ~ø|ûÉ:;.&\010•‚:Z‡ç¡ÃóÜ V““\ ! Î¥>O_ãÃZ6\026U\001 PY™\012­H”¼\027P6çl¼°—&ðr–¹\003ç–é!Àå\"×Ç\030TN\036X@„…ù¬\"Åé\012“Ê\ ! èÀ¸kݾéwË5zg?\030šƒÈaj^5\014þ\005±]Ô÷\032©Ëìý‡WNŸþ3Þž3ÝÙ­;\012b\003\030ÉI£D2»4¸\ ! Ú#[ðÜ*FK¡+F#>\027‘\027|Ä\017{I´{/`vÙœg\007J7÷{ô­ŸÓwžÙvh7ÁNçË€yã{p¹÷1O½&†\ ! oOF›²\026Q\012»½¨³…çkªÏ\022è¹h¸ÔÞØh-\012ÀØ5\014b¸ ÚÔ,Xêá\027¾ÞöîÖÅüköê¹\023ÄÅÆÙ\ ! \003Ç\023p“ûNioíêMìó¥îöS’.~UcîéÑÜø¢ýT¡»h\030|o\026þßT`u—ß›­›ËcÿŸµ\013të´­\ ! [ÎÖ\032~HÍZ\033}Qf\031þE\005Érܳ4KfTTŸ¼\035µˆ\030¹Ô®O\023%š\020µh¿\017+ùòrŒkû­–ô\033ñî\024T\ !  ›£+=}—*\002_ßÂ8µqz§o_y»;e§£Ñ©ÙƒAƒ\0073gQ¤ãáp³Ù\014r;ñ@e«¡Ã\010>·ë½uÕ¸Èær\033›E\ ! ø\023í´áŒúj\014(\027;Ê\034•›ò\005èa·ÖmJ\022h.ì5HàœÙÁXnÔܚĪN¨œ¢\004hŒ\012·úo²ô_šþ/EH\ ! SM") ### end --- 5,83 ---- import zlib ! data = zlib.decompress("xÚÝ;moÛÈÑß\017¸ÿ°Ç\"aŒÚ’l'y®²D4±}uÑäâÚº§8\034\016ÆŠ\\I[“\\–/¶Õ ÿ½3³»äòŶ\ ! Òëµ@À\022¹»³3³ó>ëÙ7gŸN\027?^ž³‹ÅÇ\017ìò‡÷\037þxʼƒñø/ǧãñÙâL\017¼\036M\016Ù\"çi!K\ ! ©R\036Ççß{Á×_Í6e\022Ó§à\021~–²Œ\005“ÑÜ£o^pñdÉ·¢`?\024\"gLK‘¯x(fcš€k\022Qr¶)Ë\ ! ì@ü­’wsï2çë„{,T0;-ç^ª\016B\036n„Çƃ\013Î\0372™‹ÂYqphæ\026å–vYªhË>³\025L˜²ßM^0ž\ ! K\036ï³â^\026Å>ÛˆøN”2ä',áùZ¦S6aÿøú«’/ž\035Öáä•Ê\023˜Û\002ðõW|\032Ëô\026Þ‡*Vù”ýf\002\ ! ?!\015òé\004–Šè‘Ѻ\003ž5co'¯'«\025Ž\014¥Œ\033ä\016î…\\o\000Ç¥Š#šq'Å=íÜ›’\002ž<ÖØ–~Ñ\"»áòá\033\032HDQðµÐçU\"C;øŠ‡†„\\ó\001ÞÑÚB„(Öö¬5Ž.r\ ! ¿ùv‚ÿNؽŒÊ\015ÈÁ›\027îBÄ\030Àvx¸Z­¸˜œ\014àá2äYÆؽ‡\026\015\037¼ÁÊH¼Ù\036@N²\007sæ¹@áÐŒ.\ ! Ø €NH\004{3‡åÕLn$î\011ˆÎ¤§€!\035e.3q£R}ž-ù\024!þ3\023+y\001fèbHnŽ&/Njèß\022ô“a¶ÍÆ\ ! ÖTÌÆÆšÁWb\"š3üâÑ;dü,’w,ŒyQÌ}­@~`FŠŒ§´\002L\003\030*/˜ÉdÍŠ<œûúÍh-W>ã±\\§\ ! sŸ/‹DFQ,üqð2]\026Ù\011à\001\020ZÐÌFú\024ìFíͲ\\EUX~Ï“–Íý‹Xº&— Oõ\\cª\022Gâ±M.V\ ! °\021<ûÁ\005üžùðv j)íõr]ž°JŽÐ\021´Qo?\000Ã4G‘s\010\"á2=ÕÚì\031\012=£ÝšÏ³Íë\000pׄ<Ã\ ! ±¼n\016 \013\026\033Y°•ŒÅ>›…*\022A\005=í³H¬d\012L(7‚ÅJÝ\036ð4:X\011\021k\020jE#\025º%iydß6,¼\0269\030\ ! á\021c\013x}\007Ö_U…\006IÁ\002W“ÔÛEà\022r\001^B0ñPæMA˜\020ìrÃË6^z½FŽ\025øQ°*c\0070Ë°…ÁÞ ²ð\037l@,ÊRXTõÚP%™JÝ\005\020§9x¹ý\ ! (âè\003(¥a\"“š}\011àƒv\025Ñ\000äîdd1°(‚é?PË¿‚é\001J³\014Ía\014xæzMÂo\001? M£—©¢`lG\032Æ\ ! 9øvÍÍš™´*\025\"*7K¡Ùg¸·A¢R#\010„§Œ,Â%_ï\023¿—\002\010ÄMÙå¶Ü€\0211Ø\001\\ÃõÑlœ¹\002õ\016¡\ ! ©ñ$‹\011“º×øÞ«ü–œ=œªÔ³\"Y.Õ\0038„r£\001ÀË..\000B¿20a\0312:8“iV•¤\016Í\024•ÛL@\000\ ! \005òãÄÅ•¨‡=†vmî\035N¼±Q­æÌ\030\034rÁ¶ªr˜Õˆ\020\034Û:çIÂK-dÓ\026õ¨•dÿÀžõÝßÛ\011þ«M\\\ ! \006l°“]£l=^\035\000¸Þ§^ŽæWÛä¹G\026ÿtâ\005ð3\033ã\010È\034Èe^:„í¸\016•ŸÍ™ÊDúÊ3ÆÀÛg^^z{\ ! àÈxôjoGH‘\012\001PƒÀ\010\015\025Ø+‘¿B »‚Ér°+\010lÔœ®=øàe\\ž\014\037}ÄO\011Â\030\015ïl,ƒÝIr°\030\021\ ! 4 Ñ;Ýðt-\"ï¿H’E¡KÒ\030ä¬ç?Œ®^+’l£Ú¨Sd'*\011μ\026ùŽiG§U\000î¢H}cÑÂàÂ\025‡°š\ ! /\025 žñ¢Dë…ÑGºFó\003Q%hþ>S¹Þ\000G\011~cA5´U®\022V„9/ÁžI\026ØÖwiÔ÷AhGÐÝå*Ž\001\007P\ ! 4\001†¹µV\025†\001´Þ‡¬ù\001\013‘O¸9\002#ý+6B”û¬ÄÌ\014´\035Ç€\\eü\033b\015F8]WH8XERE0ˆ©¸oÌm\ ! ‡I\007d¥µ\027,D\015r\002}\032x›-\023¼Øvç{\021ƒµÄ)ÚÊ÷\034kÃ,˜¡\000\01748Q惖¼¨wÀP §d.³‚\ ! \033ñy\001\005FÑ{´®\016NN f†=+M:Ò7a•\033ýû,\024q\014+CLzüÆf•y0ƒ(Ô‚ƒQ¯³Þ¼öQ{pë¹\0041\ ! \024mÍÈð—\021h\021ÀéAô%\010Â)ìë£FPX\010y”ß\001¨¯\023\020\000=qÃ@­~\020eZ`¾Ž7‹’—U¡ãM³ðõÄ\007\ ! 7†‘/}·A§\023ã!žÎ£!\032(è\004k-¼œ\025\024–¡“d\016ãA\013>ª¢\034Ž¹\012\033Iô4p@ù\013Ø\016¸\007š„ª`eÒ„\ ! bÍ\032ÐæölGtujõ\000\023µóN\007cE4\001üN«‹ª,\006ÿˆ„ÙXddM=@ø…²bh6Qû2\037w\003ß\035$WŸPK\ ! lµl\"Ïõà\002Ÿ=“\037Î=0¡®ˆÚg›§Ãs[À\006Ãw\015Ù{,“xØžA\"-ãÖŒËO—ÇŒ\0061~JÑ’\000fË ³\ ! ô\022|wqMÆÓ\013\016\017\017'†\037³ñ2Øw\027æ’1Sm \024Ëæ5\004ãE ñO\034@#\007ó†óøó\016„òNhlA\023\020\024f1\ ! íè‹»'§E×\002¢R˜é\005.ΣÎ\006}ÈÚZ\027zõSÛ”ªäñn»´²'Š‘\023<\020-Er%Ñmí¸kZ%˜5t6dð-\ ! ÙzÙEÕæÙE?¤E•‹Î²Š^v‰\\ ?˜Ð”\023Ãô©C\011b>í옷á·×\\ô—lº+žb·c\002Ñü™H×\ ! ”~ÞŠ\007ß\030M÷wgkÇÝmêR\000\010ÐJ®Ÿ2ͶB€e#<¨ª\032H•“\030~À\004Þ™ÖDZÿûGÈ\025B,0\030@\002³\ ! ‡¼I2;\\Ú\005d±-J‘€…7JGX¸)1è\035ýàÔ%\"4,9Œz'ãò×q¢µ%~ÖÒêBÖ\002âÎvàBŒl\006-\ ! \007\027­\032€6{E©ò:‹…ŒTW\034ÁÙ• †¢0H[ž’<ÓÄZg!~ä\005h.V´6ªh@è•5Ï\0326iÄüàŠ>ëùÈ\ ! #bVí›vŒ”\014¡È´áXIO ®ÖŽ\004K-àPuMÃ(+¦ç[C)xs´â5Á¦¼PS\015\016ût#Â[\"gÀLÈ\"0\ ! 7]Ve\011¼XA`-°\004@À÷ëº\002\026¾$,ó\027\010Ù‡Œ\036BL\000柉•È}Hwù)ï\030Æè¥èé÷MÙÀX\025d9¦Ã\ ! „\013\001m\"\012½èL\026!Ï#6f\004\035>ÁŒÀo\024\002fëŸ\0003$Jš\030Y¯Ö”\024:øà(\017\024\033ÙÐe­Úá25\0128M©Ï\030h\ ! \000¡€\000î\017ç\013Çf˜\022\001¥MþFF\021„;\014Kos\037¸¨€\015\030ô™¯:¡ò'®½x\002@\012\002¯×ëoƒËuZGï\004ß¼`Ø7Ÿ\ ! R,ÙK™qÕw¹J\006‡tàfcö4k\026ªYÑË\0000®4ô¶ºr`UÔ}Î3´\010\010d8âò\03256Êè#\021þ>¸Tíþ\ ! @P½À|§ cü¯A#\007M°ðÛ/€\004N˜àÀç/€‚NœÀà—vOK‹ä2\030¬€´ë5Ž¸\\©û¦\016bÛ”þðaÙ†\ ! §ß?\031Êw+êK˜Þ›‡³½ ¯iWbê\004¤ØàÐåi–«ðö\033ƾ=Øë4ë†\0139X£¼ñ‚+\031n¤`\0272@£°p\ ! ›Ó›ßƒ¡„à,Å|[—c\007¡€èºmÆ\017²(\011Ha_ý>£ÊìHåëGÀ˜ô&ĪMî÷êP½Ð%ç‘TÖƒ\032MÜN\ ! I\011ÿtþã°\003ET#-ͶÚì›çÚyöÿ\032H \032x?§çÿ,\012˜\002»!\005<ÿg\021 ´ÝA\000ŸÛ‰í€\035Õ:bw±\ ! JR?\007×Ø£\013\001\036åDO«î2æé-jnЄGÚÔ>ý؇DYÅ\016vøNŠÝãv;r4™á ~\032?o»\036\ ! XYe±âQ?‘AŽè1¯vãÄ¡–,´\034:\023\020\026\022}I\025—2ãyIX\035D¼äÖPžKê`hÐŒÛ$Ïñ *¿I°¿\024@\ ! \010—P‘¨¡†I»Åª7Ã÷–•ú»á$0Ñ9ˆO9u\004ån÷\033\025×\011&\004Š)H\033õQŒûÝ£|sê\026€1,†d™›\ ! JJ®ru\017ÎàX÷\007æ>¶Sá\\ÌLww§)¬\017ÿFkÎ<ÜoÀj·å\001C“kWµúð6_\010îâIhr>\017òÔÌ\ ! mÀYa¬k\015¯°ôbÎœÄk]í\012ë&\030©/\025v\0203êe¥‘ʨ˜|à”œdêÖ\032šv\001ËE¢îè\022F}\023`oç\ ! \012Ê=$®D¾\035Öƒz¸Q\005|õ7|å÷Yˆcžå\024|o\004ÒÉ°|Ý>õ'ÝSh3Ü\036\033„» ¯¦iï/DC,\ ! –Ú\025Ä\007&ü\035¦×™àí\026Ã7ÄãZ¯ÖÆôiâ\017w#þ\034m+•„dd»MVw±Ï‹Ûü+Œ@\016^—¼,†Ëfõ°\015Ý\ ! ¾¯’% \002\030 òÖ…»N]\032ÇBUá§Ã£ãGÚ\001\015¨Íã65 ×oÞ>\002è2WK¾”Xnu•ª1©¡¾ß ë\ ! F`°‰‡\010ZCÚE\034tké\005“Ñÿ}û»G6ü\022çbµøJ\024à\021\036asg’S¡¤2]Ö\020ˆì±=)û\016‘%6c†•\005}\ ! à\020E8]bü!c¤³Nà?Í`keº‰û,–·B3l‰2\015Æ’Õ=Ï=÷ž]ÓÔ#\030\013·¾ÚLÊ›\031\024\\ôC)\033ã\034\ ! Ïv&º·ZÁ³œ›KLxŽýêP\013Ô\020ƒz\013œ`b( p›'Yp%Ê*O›\"vû:!^£°ç\010ö›n)L‡ÏCOz§ç\ ! xÚ3X\017b|ƒ=‹½á»‡»\010\036u ¾\003hÈ\\=^‹ÛwŸ®>ZcçÑ­\014¡2\020Gkð<4xžëÔ\032pÒ¹Ñèé;Œ\ ! XÈÇŠ2\004\010TS§*3\002%ë\005M“‘—öÆ\010ÞL3\027\000Ý\036\0058¸B\024º‡Cµô‘\015ˆ°+‘× 8ÝßR9uËûÚí›\ ! y—¼Ü uöƒ±éÂŽ3óª¥ðÏ°í´¹ÔIS\026ïÞ8wæ\0147¸\007\032Ú‹+w\025ø\006P’ÃV½fqf‚ltÁs+#\ ! \035®\021ùRÄ^ð\001?ì\015Ùþ¥ˆÅY{Ÿ'Bvs¹I_y:zë™c‡qãìt\016\0161or\003&÷&á™×Žá»›Ñ¡lD\ ! œÁi‡Mêðx÷Q\000\003·L0.µ×U:DA0v\001‹\030\022Ô¨š\015–\006ð…¯Wƒ§uºü’³z¬}úï88Ûm=\0043¹ë\ ! –öʲ>Ä![ê\036?\025MéÖ[½æ†\036Íu7úØM\024úDÃâ\033CøÿSµ×%0u77çþ—¥\013dë¨+[ÎÑ\032|HÌ\ ! :\007}Zå9þ9\011ñr:@š\0053©Ûô‡o&\035 †/éÓ@\011&x-:ï½Úb>OŽ1m¿\026I¿\022îNu\005¦9²20w¥\ ! b°õ\030§QNïèÍ\013ï)\013ÛV1\015íý£*FÃú/#\036³%îœïè;sÜ\\W£\010•Ýtê)•8œL&ÿ^­\030“oí\007\ ! Aúz%Õj N\"¦ÅîF§RöŠ®}ÒLÜ`ÁÛp÷šß\011¯‰ñk¸ö\005†GÍc+XÊ…Ž;ÄŠS\000ß‹˜žÀô9´\ ! ®4lìßkà\003(¶\020üâËz›ªŒÔ}:”\020ë{$\031\036¶c®Í;Š•Ø\037”Š–ÛæO\017Ì–øGGö†3|oÒk¥J,\ ! \034Û̺\000Ö÷ój“^X\0035™¼\030jzÍœ2f4üÇKM[Â×;cÐî·ÂøGÿ¶ˆ»·ûœ&—„\034³„èÑ\013>ª\024\016'\ ! dÇ\023vøz:y==>bG“É‘9ƒQ\013\007³gYfÓñøþþ~T·\026°§0v\020Áçnñ·©¶\032\023Ù&·uX\024¢ž¶ŒÑ\ ! P\001ùbW™¾½)_€\034ö\013ߦ$êÂ^\002\007N˜]ŒåF­I¬š„Ê)J€Ä¨h«ÿ Mÿ™í?\001‹\011œÉ") ### end From mhammond at users.sourceforge.net Wed May 14 18:35:40 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Wed May 14 20:35:44 2003 Subject: [Spambayes-checkins] spambayes/testtools urlslurper.py,1.4,1.5 Message-ID: Update of /cvsroot/spambayes/spambayes/testtools In directory sc8-pr-cvs1:/tmp/cvs-serv26682 Modified Files: urlslurper.py Log Message: Old changes I forgot to check in. Allow -v to set verbosity on the command-line, and catch additional errors when processing the URL. Index: urlslurper.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/testtools/urlslurper.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** urlslurper.py 1 May 2003 23:38:47 -0000 1.4 --- urlslurper.py 15 May 2003 00:35:38 -0000 1.5 *************** *** 59,62 **** --- 59,64 ---- -f filename URL cache filename + Other options: + -v Increase verbosity. Notes: o There are lots of ways to get around this working. If the site has a *************** *** 84,88 **** from __future__ import generators ! import urllib2, socket import sys import re --- 86,90 ---- from __future__ import generators ! import urllib2, socket, httplib import sys import re *************** *** 178,182 **** if options["globals", "verbose"]: print >> sys.stderr, "Slurped." ! except (IgnoreURLException, IOError, socket.error), details: url_dict[url] = 0.5 print >> sys.stderr, "Couldn't get %s (%s)" % (url, details) --- 180,184 ---- if options["globals", "verbose"]: print >> sys.stderr, "Slurped." ! except (IgnoreURLException, IOError, socket.error, httplib.HTTPException), details: url_dict[url] = 0.5 print >> sys.stderr, "Couldn't get %s (%s)" % (url, details) *************** *** 239,243 **** try: ! opts, args = getopt.getopt(sys.argv[1:], 'hbu:p:a:o:f:n:s:', ['ham-keep=', 'spam-keep=']) except getopt.error, msg: --- 241,245 ---- try: ! opts, args = getopt.getopt(sys.argv[1:], 'hbu:p:a:o:f:n:s:v', ['ham-keep=', 'spam-keep=']) except getopt.error, msg: *************** *** 269,272 **** --- 271,276 ---- elif opt == '-s': seed = int(arg) + elif opt == '-v': + options["globals", "verbose"] = 1 elif opt == '--ham-keep': hamkeep = int(arg) From mhammond at users.sourceforge.net Wed May 14 18:36:54 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Wed May 14 20:36:58 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000 msgstore.py,1.42,1.43 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000 In directory sc8-pr-cvs1:/tmp/cvs-serv27806 Modified Files: msgstore.py Log Message: Give a less severe warning for "folder temporarily unavailable" Index: msgstore.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/msgstore.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** msgstore.py 12 May 2003 23:26:35 -0000 1.42 --- msgstore.py 15 May 2003 00:36:52 -0000 1.43 *************** *** 96,103 **** --- 96,110 ---- USE_DEFERRED_ERRORS = mapi.MAPI_DEFERRED_ERRORS # or set to zero to see what changes + # Does this exception probably mean "object not found"? def IsNotFoundCOMException(exc_val): hr, msg, exc, arg_err = exc_val return hr in [mapi.MAPI_E_OBJECT_DELETED, mapi.MAPI_E_NOT_FOUND] + # Does this exception probably mean "object not available 'cos you ain't logged + # in, or 'cos the server is down"? + def IsNotAvailableCOMException(exc_val): + hr, msg, exc, arg_err = exc_val + return hr == mapi.MAPI_E_FAILONEPROVIDER + def GetCOMExceptionString(exc_val): hr, msg, exc, arg_err = exc_val *************** *** 224,229 **** except pythoncom.com_error, details: # We will ignore *all* such errors for the time ! # being, but warn for results we don't know about. ! if not IsNotFoundCOMException(details): print "WARNING: Unexpected MAPI error opening folder" print GetCOMExceptionString(details) --- 231,241 ---- except pythoncom.com_error, details: # We will ignore *all* such errors for the time ! # being, but give verbose details for results we don't ! # know about ! if IsNotAvailableCOMException(details): ! print "NOTE: Skipping folder for this session - temporarily unavailable" ! elif IsNotFoundCOMException(details): ! print "NOTE: Skipping deleted folder" ! else: print "WARNING: Unexpected MAPI error opening folder" print GetCOMExceptionString(details) From mhammond at users.sourceforge.net Wed May 14 19:00:08 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Wed May 14 21:00:10 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000/dialogs FolderSelector.py, 1.16, 1.17 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000/dialogs In directory sc8-pr-cvs1:/tmp/cvs-serv16003 Modified Files: FolderSelector.py Log Message: Fix [ 737956 ] No hourglass when building folder lists Index: FolderSelector.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/dialogs/FolderSelector.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** FolderSelector.py 18 Mar 2003 00:03:26 -0000 1.16 --- FolderSelector.py 15 May 2003 01:00:04 -0000 1.17 *************** *** 54,57 **** --- 54,59 ---- def _BuildFoldersMAPI(manager, folder_id): + # This is called dynamically as folders are expanded. + win32ui.DoWaitCursor(1) folder = manager.message_store.GetFolder(folder_id).OpenEntry() # Get the hierarchy table for it. *************** *** 78,81 **** --- 80,84 ---- spec.children = None # Flag as "not yet built" children.append(spec) + win32ui.DoWaitCursor(0) return children *************** *** 311,314 **** --- 314,318 ---- # Build list of all ids to expand - ie, list includes all # selected folders, and all parents. + win32ui.DoWaitCursor(1) self.expand_ids = self._DetermineFoldersToExpand() tree = BuildFolderTreeMAPI(self.manager.message_store.session) *************** *** 317,320 **** --- 321,325 ---- self.expand_ids = [] # Only use this while creating dialog. self._UpdateStatus() + win32ui.DoWaitCursor(0) return dialog.Dialog.OnInitDialog (self) From ta-meyer at ihug.co.nz Thu May 15 14:02:11 2003 From: ta-meyer at ihug.co.nz (Tony Meyer) Date: Wed May 14 21:02:51 2003 Subject: [Spambayes-checkins] spambayes/testtools urlslurper.py,1.4,1.5 In-Reply-To: <1ED4ECF91CDED24C8D012BCF2B034F1301961A68@its-xchg4.massey.ac.nz> Message-ID: <1ED4ECF91CDED24C8D012BCF2B034F13C8CB52@its-xchg4.massey.ac.nz> > Modified Files: > urlslurper.py > Log Message: > Old changes I forgot to check in. Allow -v to set verbosity > on the command-line, and catch additional errors when > processing the URL. I meant to ask you this last time - does the fact that you're fixing up the code mean that that you're testing how well this works? I'm curious whether this gives enough improvement to be added as an option or not, and no-one else seems to be interested in testing it... =Tony Meyer From mhammond at users.sourceforge.net Wed May 14 19:04:23 2003 From: mhammond at users.sourceforge.net (Mark Hammond) Date: Wed May 14 21:04:26 2003 Subject: [Spambayes-checkins] spambayes/Outlook2000 addin.py, 1.55, 1.56 manager.py, 1.56, 1.57 Message-ID: Update of /cvsroot/spambayes/spambayes/Outlook2000 In directory sc8-pr-cvs1:/tmp/cvs-serv19732 Modified Files: addin.py manager.py Log Message: Fix [ 737955 ] Transient connection error disables plugin Index: addin.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/addin.py,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** addin.py 3 May 2003 12:36:49 -0000 1.55 --- addin.py 15 May 2003 01:04:20 -0000 1.56 *************** *** 3,6 **** --- 3,7 ---- import sys, os import warnings + import traceback try: *************** *** 654,683 **** def OnConnection(self, application, connectMode, addin, custom): print "SpamAddin - Connecting to Outlook" - self.application = application - - # Create our bayes manager import manager ! self.manager = manager.GetManager(application) ! assert self.manager.addin is None, "Should not already have an addin" ! self.manager.addin = self ! ! explorers = application.Explorers ! # and Explorers events so we know when new explorers spring into life. ! self.explorers_events = WithEvents(explorers, ExplorersEvent) ! self.explorers_events.Init(self.manager) ! # And hook our UI elements to all existing explorers ! for i in range(explorers.Count): ! explorer = explorers.Item(i+1) ! self.explorers_events._DoNewExplorer(explorer, True) ! ! if self.manager.config.filter.enabled: ! self.FiltersChanged() ! try: ! self.ProcessMissedMessages() ! except: ! print "Error processing missed messages!" ! import traceback ! traceback.print_exc() def ProcessMissedMessages(self): --- 655,693 ---- def OnConnection(self, application, connectMode, addin, custom): + # Handle failures during initialization so that we are not + # automatically disabled by Outlook. + # Our error reporter is in the "manager" module, so we get that first print "SpamAddin - Connecting to Outlook" import manager ! try: ! self.application = application ! self.manager = None # if we die while creating it! ! # Create our bayes manager ! self.manager = manager.GetManager(application) ! assert self.manager.addin is None, "Should not already have an addin" ! self.manager.addin = self ! ! explorers = application.Explorers ! # and Explorers events so we know when new explorers spring into life. ! self.explorers_events = WithEvents(explorers, ExplorersEvent) ! self.explorers_events.Init(self.manager) ! # And hook our UI elements to all existing explorers ! for i in range(explorers.Count): ! explorer = explorers.Item(i+1) ! self.explorers_events._DoNewExplorer(explorer, True) ! ! if self.manager.config.filter.enabled: ! self.FiltersChanged() ! try: ! self.ProcessMissedMessages() ! except: ! print "Error processing missed messages!" ! traceback.print_exc() ! except: ! print "Error connecting to Outlook!" ! traceback.print_exc() ! manager.ReportError( ! "There was an error initializing the SpamBayes addin\r\n\r\n" ! "Please re-start Outlook and try again.") def ProcessMissedMessages(self): *************** *** 744,748 **** new_hooks[msgstore_folder.id] = new_hook self.manager.EnsureOutlookFieldsForFolder(msgstore_folder.GetID()) ! print "AntiSpam: Watching for new messages in folder", name else: new_hooks[msgstore_folder.id] = existing --- 754,758 ---- new_hooks[msgstore_folder.id] = new_hook self.manager.EnsureOutlookFieldsForFolder(msgstore_folder.GetID()) ! print "AntiSpam: Watching for new messages in folder ", name else: new_hooks[msgstore_folder.id] = existing Index: manager.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/Outlook2000/manager.py,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** manager.py 3 May 2003 12:36:49 -0000 1.56 --- manager.py 15 May 2003 01:04:20 -0000 1.57 *************** *** 78,81 **** --- 78,92 ---- pass + # Report a message to the user - should only be used for pretty serious errors + # hence we also print a traceback. + # Module level function so we can report errors creating the manager + def ReportError(message, title = None): + import traceback + print "ERROR:", message + traceback.print_exc() + if title is None: + title = "SpamBayes Anti-Spam plugin" + win32ui.MessageBox(message, title) + # Function to "safely" save a pickle, only overwriting # the existing file after a successful write. *************** *** 184,197 **** self.message_store = msgstore.MAPIMsgStore(outlook) - # Report a message to the user - should only be used for pretty serious errors - # hence we also print a traceback. def ReportError(self, message, title = None): ! import traceback ! print "ERROR:", message ! traceback.print_exc() ! if title is None: ! title = "SpamBayes Anti-Spam plugin" ! win32ui.MessageBox(message, title) ! # Report a super-serious startup error to the user. # This should only be used when SpamBayes was previously working, but a --- 195,201 ---- self.message_store = msgstore.MAPIMsgStore(outlook) def ReportError(self, message, title = None): ! ReportError(message, title) ! # Report a super-serious startup error to the user. # This should only be used when SpamBayes was previously working, but a From anadelonbrin at users.sourceforge.net Wed May 14 19:29:14 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Wed May 14 21:29:17 2003 Subject: [Spambayes-checkins] spambayes/spambayes UserInterface.py, 1.10, 1.11 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes In directory sc8-pr-cvs1:/tmp/cvs-serv14384/spambayes Modified Files: UserInterface.py Log Message: Missing import as reported by Peter Bengtsson. Added extra stuff to try and convince browsers to not cache the user interface, as recommended by Richard Jowsey. Index: UserInterface.py =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/UserInterface.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** UserInterface.py 14 May 2003 00:18:19 -0000 1.10 --- UserInterface.py 15 May 2003 01:29:11 -0000 1.11 *************** *** 71,74 **** --- 71,75 ---- import mailbox import types + import StringIO import PyMeldLite From anadelonbrin at users.sourceforge.net Wed May 14 19:29:14 2003 From: anadelonbrin at users.sourceforge.net (Tony Meyer) Date: Wed May 14 21:29:18 2003 Subject: [Spambayes-checkins] spambayes/spambayes/resources ui.html, 1.13, 1.14 ui_html.py, 1.13, 1.14 Message-ID: Update of /cvsroot/spambayes/spambayes/spambayes/resources In directory sc8-pr-cvs1:/tmp/cvs-serv14384/spambayes/resources Modified Files: ui.html ui_html.py Log Message: Missing import as reported by Peter Bengtsson. Added extra stuff to try and convince browsers to not cache the user interface, as recommended by Richard Jowsey. Index: ui.html =================================================================== RCS file: /cvsroot/spambayes/spambayes/spambayes/resources/ui.html,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** ui.html 14 May 2003 00:18:19 -0000 1.13 --- ui.html 15 May 2003 01:29:12 -0000 1.14 *************** *** 4,8 **** Spambayes User Interface !