[Tess-developers] TheSpamSecretary COOKBOOK,NONE,1.1 README,NONE,1.1 TheSpamSecretary.py,1.9,1.10
Brought to you by:
kwerle
|
From: <kw...@us...> - 2003-01-07 04:55:22
|
Update of /cvsroot/tess/TheSpamSecretary In directory sc8-pr-cvs1:/tmp/cvs-serv1858 Modified Files: TheSpamSecretary.py Added Files: COOKBOOK README Log Message: Added exit status, - goes to stdout for procmail and friends. --- NEW FILE: COOKBOOK --- Full of good recipes! (to come) --- NEW FILE: README --- This assumes you use mbox format and do not use procmail for mail delivery. It also assumes the following email usage pattern: Incoming mail goes to your inbox, or spam box depending on status. You move read mail to a Deleted box. You move verified spam to a VerifiedSpam box. You want both your Deleted box and VerifiedSpam box truncated to length 0 every time you receive new mail! If this does not match your usage pattern, check out the COOKBOOK To install if you don't use procmail!!!: (as root) cp TheSpamSecretary.py /usr/local/bin [or wherever you like] (as you) python /usr/local/bin/TheSpamSecretary.py This will generate the needed .TheSpamSecretary... files in your home directory. Then you must edit ~/.TheSpamSecretary.config MAKE SURE that your inboxpath is the correct path to your mail inbox. The same goes for your spam box - make sure it exists and is correct. Then edit (don't forget to keep a backup if you already have one) ~/.forward It should look like this (include the "'s): "|/<pathto>/TheSpamSecretary.py --filter --addbad=<path to your verified spam box> --addgood=<path to your deleted good mail box> --delete=0" This will filter the incoming message and also add the contents of the bad box to the bad dictionary, and the good box to the good dictionary. It will not truncate the files when it is done. TEST THIS BY SENDING YOURSELF MAIL. If it arrives in your inbox, things are going well. If it doesn't, you can check the cookbook and try to debug it, or ask for help on the user list at http://lists.sourceforge.net/mailman/listinfo/tess-users. Otherwise, you should remove/revert your .forward file. If this worked, you're well on your way! If you had deleted messages in your Deleted box, you can make sure they were loaded by doing something like TheSpamSecretary.py --showgood | more Similarly, you can try TheSpamSecretary.py --showbad | more to check any spam messages. Once you're convinced incoming mail is working, you should edit your .forward again and change --delete=0 to --delete=1 . THIS WILL CONSUME YOUR Deleted MAILBOX AND VerifiedSpam MAILBOX EVERY TIME YOU RECEIVE MAIL. If this is not the behavior you want, please check out the COOKBOOK. If you did not have a store of deleted mail to be consumed, I recommend copying (make sure it is COPY and not move) your inbox to your deleted box. That way TeSS gets an idea of what you think of as not spam. TeSS will not filter mail until it has parsed at least 40 GOOD messages. Otherwise it tends to get a lot of false positives early on. After that, it seems to be smooth sailing! Index: TheSpamSecretary.py =================================================================== RCS file: /cvsroot/tess/TheSpamSecretary/TheSpamSecretary.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** TheSpamSecretary.py 5 Jan 2003 21:21:10 -0000 1.9 --- TheSpamSecretary.py 7 Jan 2003 04:55:19 -0000 1.10 *************** *** 32,37 **** #-------------------------------------------------------------------------- - #import mailbox import array import getopt import ConfigParser --- 32,37 ---- #-------------------------------------------------------------------------- import array + import atexit import getopt import ConfigParser *************** *** 67,70 **** --- 67,71 ---- Generate the filter dict. Proceed according to the commands. """ + self.exitStatus = 0 self.goodDict = {} self.goodMessageCount = 0 *************** *** 91,102 **** username = 'YOUR_NAME' self.inboxPath = os.path.join("/var/mail", username) ! self.deleteBoxPath = os.path.join(user.home, "mail/Deleted") self.spamBoxPath = os.path.join(user.home, "mail/Spam") ! self.verifiedspamBoxPath = os.path.join(user.home, "mail/VerifiedSpam") self.newGoodPath = None self.newBadPath = None self.filter = 0 self.loadedMessageCount = 0 self.__loadConfig() self.logFile = open(os.path.join(self.home, "TheSpamSecretary.log"), "a") --- 92,106 ---- username = 'YOUR_NAME' self.inboxPath = os.path.join("/var/mail", username) ! #self.deleteBoxPath = os.path.join(user.home, "mail/Deleted") self.spamBoxPath = os.path.join(user.home, "mail/Spam") ! #self.verifiedspamBoxPath = os.path.join(user.home, "mail/VerifiedSpam") self.newGoodPath = None self.newBadPath = None self.filter = 0 self.loadedMessageCount = 0 + + atexit.register(self.exitstatus) + # Start initialization from loading files self.__loadConfig() self.logFile = open(os.path.join(self.home, "TheSpamSecretary.log"), "a") *************** *** 105,108 **** --- 109,113 ---- self.__loadDictionaries() + # Start actually doing things if (self.newGoodPath and not self.dictFailure): self.addToDict(self.goodDict, self.goodMessageCount, self.goodDictPath, self.newGoodPath) *************** *** 169,173 **** """ try: ! (opts, args) = getopt.getopt(cmd[1:], "", ["addgood=", "addbad=", "config=", "delete=", "filter", "showgood", "showbad", "showfilter", "debugFilter", "license"]) except: sys.stderr.write(""" --- 174,178 ---- """ try: ! (opts, args) = getopt.getopt(cmd[1:], "", ["addgood=", "addbad=", "config=", "delete=", "filter", "showgood", "showbad", "debugFilter", "license"]) except: sys.stderr.write(""" *************** *** 192,196 **** --showgood will dump the good dict to stdout and exit --showbad will dump the bad dict to stdout and exit - --showfilter will dump the filter dict to stdout and exit --debugFilter will scan text from Standard Input and print the spam match dict --- 197,200 ---- *************** *** 221,232 **** self.__loadDictionaries() self.__showDict(self.badDict) - if (o == "--showfilter"): - self.__loadConfig() - self.__loadDictionaries() - # self.__generateFilterDict() - # print(self.filterDict) - print("Good messages read: %d" % self.goodMessageCount) - print("Bad messages read: %d" % self.badMessageCount) - if (o == "--debugFilter"): self.__loadConfig() --- 225,228 ---- *************** *** 287,291 **** needConfig = 0 if (os.access(self.configPath, os.R_OK) == 0): ! sys.stderr.write("ERROR: %s does not exist or is unreadable. Exiting...\n" % self.configPath) needConfig = 1 --- 283,288 ---- needConfig = 0 if (os.access(self.configPath, os.R_OK) == 0): ! sys.stderr.write("ERROR: %s does not exist or is unreadable.\n" % self.configPath) ! sys.stderr.write(" Writing a new one. Please make sure it is correct.\n") needConfig = 1 *************** *** 306,312 **** self.badDictPath = self.__getDefault(configparser, "badDictPath", defaultValue = self.badDictPath) self.inboxPath = self.__getDefault(configparser, "inboxPath", defaultValue = self.inboxPath) ! self.deleteBoxPath = self.__getDefault(configparser, "deleteBoxPath", defaultValue = self.deleteBoxPath) self.spamBoxPath = self.__getDefault(configparser, "spamBoxPath", defaultValue = self.spamBoxPath) ! self.verifiedspamBoxPath = self.__getDefault(configparser, "verifiedspamBoxPath", defaultValue = self.verifiedspamBoxPath) self.deleteFiles = self.__getDefault(configparser, "deleteFiles", defaultValue = self.deleteFiles) try: --- 303,309 ---- self.badDictPath = self.__getDefault(configparser, "badDictPath", defaultValue = self.badDictPath) self.inboxPath = self.__getDefault(configparser, "inboxPath", defaultValue = self.inboxPath) ! #self.deleteBoxPath = self.__getDefault(configparser, "deleteBoxPath", defaultValue = self.deleteBoxPath) self.spamBoxPath = self.__getDefault(configparser, "spamBoxPath", defaultValue = self.spamBoxPath) ! #self.verifiedspamBoxPath = self.__getDefault(configparser, "verifiedspamBoxPath", defaultValue = self.verifiedspamBoxPath) self.deleteFiles = self.__getDefault(configparser, "deleteFiles", defaultValue = self.deleteFiles) try: *************** *** 384,394 **** #sys.stdin.seek(0) #tempFile = sys.stdin ! if (final_odds < .9): #print("looks clean") ! destFile = open(self.inboxPath, "a") else: #print("looks like spam") ! destFile = open(self.spamBoxPath, "a") ! fcntl.lockf(destFile.fileno(), fcntl.LOCK_EX); while 1: oneLine = tempFile.readline() --- 381,399 ---- #sys.stdin.seek(0) #tempFile = sys.stdin ! if (final_odds < .90): #print("looks clean") ! if (self.inboxPath == "-"): ! destFile = sys.stdout ! else: ! destFile = open(self.inboxPath, "a") ! fcntl.lockf(destFile.fileno(), fcntl.LOCK_EX); else: #print("looks like spam") ! if (self.spamBoxPath == "-"): ! destFile = sys.stdout ! self.exitStatus = 1 ! else: ! destFile = open(self.spamBoxPath, "a") ! fcntl.lockf(destFile.fileno(), fcntl.LOCK_EX); while 1: oneLine = tempFile.readline() *************** *** 398,402 **** tempFile.close() os.remove(tempFileName) ! destFile.close() #print(interest_dict.keys().sort()) #print(interest_dict) --- 403,408 ---- tempFile.close() os.remove(tempFileName) ! if (destFile != sys.stdout): ! destFile.close() #print(interest_dict.keys().sort()) #print(interest_dict) *************** *** 570,573 **** --- 576,587 ---- ################################################## + def exitstatus(self): + """ + Looks like this is not needed, but I'm keeping it for now... + """ + #print("Over and %d" % self.exitStatus) + + ################################################## + def scanMessageFile(self, messageFile): """ *************** *** 637,640 **** --- 651,655 ---- boxScanner = TheSpamSecretary() + sys.exit(boxScanner.exitStatus) ## EOF ## |