Re: SA-learn on remote host
On Fri, Sep 14, 2007 at 09:23:16PM +0100, John K Masters <johnmasters@oxtedonline.net> was heard to say:
> I am gradually implementing a mail system where I have a mail-server on
> host1 running Postfix/Courier/Procmail/spamc which passes all except
> whitelisted mail to spamd on another server - host2. host2 simply runs
> the mail through SA and passes it back to host1 from which I read on my
> local box via Mutt.
>
> Most spam gets filtered into the .Spam folder and I have bound keys in
> Mutt to move missed spam to this folder and to copy good messages to a
> .Ham folder.
>
> What I would like to do now is have a cronjob run the contents of these
> two folders through SA-learn and then delete them. ATM I am stumped as
> to how to go about this. Any pointers very welcome.
I use IMAP to synchronize my mail across systems (sounds like you do
too?), and just run the attached script over folders holding spam and
ham to learn. (warning: it's quick and dirty, won't work for anyone
else without tweaks!)
Daniel
#!/usr/bin/python
#
# Process spam in the maildir ~/Mail/spam-to-learn and ham in the
# maildir ~/Mail/ham-to-learn, clearing both maildirs as we work.
# This is meant to be run as a cronjob and will lock other instances
# of itself out. Note: the locking mechanism assumes that flock()
# behaves sanely; you may not want to use this if you have a
# networked $HOME. (it has the benefit that the lock is
# automatically dropped if the process dies unexpectedly)
import fcntl
import os
import sys
home = os.environ['HOME']
lockfile = '%s/.learnspam-lock' % home
f = file(lockfile, 'w')
try:
fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
print 'learnspamjob already running'
sys.exit(0)
quiet = not os.isatty(1)
def dolistdir(dirname):
return ['%s/%s'%(dirname, x) for x in os.listdir(dirname)]
# Process and delete each message in the maildir with the given
# command template.
def process_maildir(dname, cmd):
files = dolistdir('%s/cur'%dname) + dolistdir('%s/new'%dname)
for f in files:
rval = os.system(cmd % f)
if not os.WIFEXITED(rval):
if os.WIFSIGNALED(rval):
msg = '"%s" terminated with signal %d' % (cmd % f, os.WTERMSIG(rval))
elif os.WIFSTOPPED(rval):
msg = '"%s" unexpectedly stopped' % (cmd % f)
elif os.WIFCONTINUED(rval):
msg = '"%s" unexpectedly continued' % (cmd % f)
if os.WCOREDUMP(rval):
msg += ' (core dumped)'
sys.stderr.write('ERROR processing %s: %s\n'%(f, msg))
elif os.WEXITSTATUS(rval) <> 0:
sys.stderr.write('ERROR processing %s: "%s" exited with status %d'%(f, cmd % f, os.WEXITSTATUS(rval)))
else:
try:
os.unlink(f)
except OSError, e:
sys.stderr.write('Unable to unlink %s: %s\n'%(f, e.strerror))
process_maildir('%s/Mail/spam-to-learn' % home, 'spamassassin -r %s > /dev/null')
process_maildir('%s/Mail/ham-to-learn' % home, 'sa-learn --ham %s > /dev/null')
Reply to: