[Spambayes] popget.py - Gnus mail fetcher
Paul Moore
lists@morpheus.demon.co.uk
Sun Nov 17 16:50:56 2002
I use Gnus on Windows for my mailreader at home, with Hamster (a local
mail/news server) as my POP3 mailbox. I could use pop3proxy for spam
detection, but it has a couple of problems:
1. As I already have a local POP server, I have to use a non-standard
port
2. I have to remember to start the program, or package it up as a
service, or otherwise automate the startup and hide the console
window.
Rather than this, I wrote a small program (attached) to grab the
contents of a POP mailbox into a local file, scoring messages as it
goes. I can then put the following in my .gnus.el file to run my mail
through spambayes. It's equally usable on Unix, for people who have
reasons for not wanting to use pop3proxy there.
--- .gnus.el snippet ---
;; Popget program from spambayes setup
(setq popget "C:\\Data\\spambayes\\spambayes-test\\popget.bat")
;; Get mail via POP3
(setq mail-sources
'((pop :server "localhost"
:user "XXXXXX"
:password "XXXXXX"
:program (concat popget " -u %u/%p -P %P -s %s -f %t"))))
------------------------
This works beautifully, and combined with XEmacs mail splitting, I
have a nice spam detection facility. With a little bit of work (not
hard) I can also use the new hammiefilter.py to add training
keystrokes, and I have quite a nice setup.
One other thing I'm going to add is a way to display the spam clues
for the current message in a buffer. When I'm done, I'll package up
the code in a form that can be included in the project as a sample
Gnus setup.
Paul.
-------------- next part --------------
#!/usr/bin/env python
# A program to get and classify the contents of a POP3 mailbox.
"""Usage: %(program)s [options]
Where:
-h
Show usage and exit
-s SERVER
The server from which to get the mail (default localhost)
-P PORT
The port to use (default 110)
-u USER/PASS
The username and password of the POP3 account
-f FILE
The file to save messages in (defaults to stdout)
-k
Keep messages on the POP server (default is to delete them)
-p FILE
use file as the persistent store. loads data from this file if it
exists, and saves data to this file at the end.
Default: %(DEFAULTDB)s
-d
use the DBM store instead of cPickle. The file is larger and
creating it is slower, but checking against it is much faster,
especially for large word databases. Default: %(USEDB)s
-D
the reverse of -d: use the cPickle instead of DBM
"""
import os
import sys
import getopt
import poplib
import socket
import hammie
from Options import options
try:
True, False
except NameError:
# Maintain compatibility with Python 2.2
True, False = 1, 0
# For usage(); referenced by docstring above
program = sys.argv[0]
DEFAULTDB = options.persistent_storage_file
class Config:
def __init__(self):
self.server = 'localhost'
self.port = 110
self.user = None
self.password = None
self.DB = DEFAULTDB
self.use_db = options.persistent_use_database
self.filename = "<stdout>"
self.file = sys.stdout
self.delete = True
def createhammie(self):
bayes = hammie.createbayes(self.DB, self.use_db)
self.hammie = hammie.Hammie(bayes)
FROMLINE = "From popget@spambayes.org Sat Jan 31 00:00:00 2000"
def getmail(conf):
pop = poplib.POP3(conf.server, conf.port)
if conf.user:
pop.user(conf.user)
if conf.password:
pop.pass_(conf.password)
n, size = pop.stat()
num = 1
while num <= n:
rsp, lines, size = pop.retr(num)
msg = "\n".join(lines)
print >>conf.file, FROMLINE
print >>conf.file, conf.hammie.filter(msg)
print >>conf.file
if conf.delete:
pop.dele(num)
num += 1
pop.quit()
def usage(code, msg=''):
"""Print usage message and sys.exit(code)."""
if msg:
print >> sys.stderr, msg
print >> sys.stderr
print >> sys.stderr, __doc__ % globals()
sys.exit(code)
def main():
"""Main program - parse options and run."""
try:
opts, args = getopt.getopt(sys.argv[1:], "hs:P:u:f:kp:dD")
except getopt.error, msg:
usage(2, msg)
if not opts:
usage(2, "No options given")
conf = Config()
for opt, arg in opts:
if opt == '-h':
usage(0)
elif opt == '-s':
conf.server = arg
elif opt == '-P':
try:
conf.port = int(arg)
except ValueError:
usage(2, "Port must be a number ('%s' given)" % arg)
elif opt == '-u':
try:
conf.user, conf.password = arg.split("/",1)
except ValueError:
usage(2, "-u option is USER/PASS ('%s' given)" % arg)
elif opt == '-k':
conf.delete = False
elif opt == '-f':
# Need to expand ~
conf.filename = os.path.expanduser(arg)
conf.file = open(conf.filename, "w")
elif opt == '-p':
conf.DB = arg
elif opt == '-d':
conf.use_db = True
elif opt == '-D':
conf.use_db = False
conf.createhammie()
try:
getmail(conf)
except (poplib.error_proto, socket.error), e:
print >> sys.stderr, "POP protocol error %s" % e
sys.exit(1)
if __name__=="__main__":
main()
-------------- next part --------------
--
This signature intentionally left blank
More information about the Spambayes
mailing list