Here's a python script to increment an emails spam score. I call it (potentially several times) after SpamAssassin and before final delivery.
download: incspam
#!/usr/bin/env python
"""
Usage:
cat email | incspam increment [comment]
ex. incspam 2 "keyword: viagra" < email.file
Description:
pipe in an email on stdin, argument is how many X to add to X-Spam-Level
dumps new msg to stdout, used by procmail
:0 fw
* some condition
| incmail 2 comment
Caveat:
This process may change some cr/lf and header spacing/breaking but should be email client safe
"""
import os,sys
import re
import subprocess
import email
from cStringIO import StringIO
from email.Generator import Generator
def msg_to_string(msg):
fp = StringIO()
g = Generator(fp, mangle_from_=False)
g.flatten(msg,True)
return fp.getvalue()
try:
if len(sys.argv) < 2:
raise
else:
inc=int(sys.argv[1])
if inc < 1: # we don't want to mess with headers if we aren't going do anything worthwhile
raise # we may want to have the ability to subract from the score in the future
try:
comment=sys.argv[2]
except IndexError:
comment=""
orig_msg=sys.stdin.read()
msg=email.message_from_string(orig_msg)
h_level="X-Spam-Level"
h_flag="X-Spam-Flag"
h_comment="X-Spam-Inc"
for header in (h_level, h_flag, h_comment):
if not msg.has_key(header):
msg.add_header(header, "")
msg.replace_header(h_flag,"YES")
# set the number of X's
level=len(msg.get(h_level)) + inc
msg.replace_header(h_level,"X"*level)
# add a note saying how this msg is getting incremented
t_comment=msg.get(h_comment)
if len(t_comment):
t_comment= t_comment + ", "
t_comment += comment + " +" + str(inc)
msg.replace_header(h_comment,t_comment)
h_subject="Subject"
subject=msg.get(h_subject)
re_spam=re.compile("\[spam\+?\] ")
if re_spam.match(subject): # strip out [spam+?] from subject
pos=subject.find(" ") + 1 # find then skip space
subject = subject[pos:]
subject="[spam+] " + subject # prepend [spam+] to subject
msg.replace_header(h_subject,subject)
print msg_to_string(msg)
except: # if anything bad happens then just print out original stdin
try:
print orig_msg
except NameError: # orig_msg doesn't exist yet
print sys.stdin.read()