This is my personal twist to the whole mailcleaner imap training thing...
I added a few things and consolidated a new feature from the original author.
Thomas Nelson
Perfection PC
Spokane, WA
Code:
#!/usr/bin/perl
# Imap Interface to SpamAssassin Learn v0.03B
# ------------------------------------ -----
#
# Connects to an imap server, and filters the messages from the INBOX
# and SpamTrap (unless otherwise told) through sa-learn
#
# usage:
# imap-sa-learn.pl <-hamfolder HAM> <-spamfolder SPAM>
#
# Other options:
# -skips nnn skips over the first nnn messages in the folder(s)
# -deletespam after learning from a spam message, delete it
# -delete-spam (as above)
# -dangerous-delete-ham after learning from a ham (real email),
# delete it. Most people don't want this...
# -dangerous-delete-all after learning from any message, delete
# it, spam or ham
#
# Uses Mail::IMAPClient and SpamAssassin (sa-learn)
#
# Needs a version of SpamAssassin with the Bayesian filtering support,
# i.e. 2.50 or later
#
# Nick Burch <nick@tirian.magd.ox.ac.uk>
# 25/06/2003
#
# Changes:
# Added SSL connection to work with Exchange 2007 from Nick's work.
# Added bogofilter to the script so it creates a new bogofilter and spamassassin filter.
# Added a seperate section for spam and ham. (we have seperate e-mail accounts for spam and ham.)
# Restored the debugging feature to IMAPClient.
# Added several break points that give some debuggin information if there is an error.
#
# Thomas Nelson <tom AT perfectionpc.com>
# 15/04/2009
use Mail::IMAPClient;
use IO::Socket::SSL;
# Define our server and credentials here
# your details go below
my $spamusername = 'spam_account';
my $spampassword = 'spam_password';
my $spamserver = 'spam_server';
my $hamusername = 'ham_account';
my $hampassword = 'ham_password';
my $hamserver = 'ham_server';
# Define where to find messages
my $defspamfolder = 'INBOX';
my $defhamfolder = 'INBOX';
my $deletespam = 1;
my $deleteham = 1;
my $default = 1;
my $skips = 0;
# Output: Normal (1), Debugging (2), or silent(0)?
my $debug = 0;
my @spams;
my @hams;
while(my $arg = shift) {
if($arg eq "-spamfolder") {
my $spam = shift;
push @spams,$spam;
print "Using spam folder $spam\n";
$default = 0;
}
if($arg eq "-hamfolder") {
my $ham = shift;
push @hams,$ham;
print "Using normal (ham) folder $ham\n";
$default = 0;
}
if($arg eq "-deletespam" || $arg eq "-deletespams" || $arg eq "-delete-spam" || $arg eq "-delete-spams") {
$deletespam = 1;
}
if($arg eq "-dangerous-delete-ham" || $arg eq "-dangerous-delete-hams") {
$deleteham = 1;
}
if($arg eq "-dangerous-delete-all") {
$deletespam = 1;
$deleteham = 1;
}
if($arg eq "-skips" || $arg eq "-skip") {
$skips = shift;
}
if($arg eq "-?" || $arg eq "-h") {
print "Usage:\n";
print " imap-sa-learn.pl [-spamfolder f]* [-hamfolder f]*\n\n";
print "with no argumnets, uses default folders\n";
print "(a few other options exist, see the header of the program)\n";
exit;
}
}
if($default) {
push @hams,$defhamfolder;
push @spams,$defspamfolder;
}
my %folders;
$folders{'spam'} = \@spams;
$folders{'ham'} = \@hams;
# Open an SSL session to the IMAP server
# Handles the SSL setup, and gives us back a socket
my $ssl=new IO::Socket::SSL("$spamserver:imaps");
die ("Error connecting - $@") unless defined $ssl;
$ssl->autoflush(1);
# Connect to the IMAP server in peek (i.e. don't set read flag) mode
my $imap = Mail::IMAPClient->new(
Debug => $debug,
Socket => $ssl,
Server => $spamserver,
User => $spamusername,
Password => $spampassword,
Peek => 1) or die "Cannot connect to $spamserver as $spamusername: $@";
$type = 'spam';
foreach my $folder (@{$folders{$type}}) {
print "\nLooking in $type folder $folder\n";
# Pick the folder
$imap->select($folder) or die "Cannot connect to $folder on $spamserver: $@";
# Enable peek mode
$imap->Peek(1);
# Fetch messages
my @mails = ($imap->seen(),$imap->unseen);
my $count = 0;
foreach my $id (@mails) {
$count++;
if($count < $skips) { next; }
print " Learning on $type message $id\n";
my $mail = $imap->message_string($id) or die "Cannot fetch $id in $folder: $@";
open SA, "| sa-learn -p /usr/mailcleaner/etc/mailscanner/spam.assassin.prefs.conf --siteconfigpath /usr/mailcleaner/share/spamassassin --no-sync --$type --single";
print SA $mail;
close SA;
# Bogofilter section
open BF, "| /usr/bogofilter/bin/bogofilter -s";
print BF $mail;
close BF;
if($type eq "spam" && $deletespam) {
# If you want to move the message rather than deleting it,
# uncomment the line below, change the folder, but _don't_
# remove the delete line!
#$imap->append('TrashBin', $mail );
print "Deleting Spam Message $id\n";
$imap->delete_message($id);
}
if($deletespam) {
# Only expunge now, rather than on every message
$imap->expunge();
}
}
}
$imap->close;
$ssl->close;
# Open an SSL session to the IMAP server
# Handles the SSL setup, and gives us back a socket
my $ssl=new IO::Socket::SSL("$hamserver:imaps");
die ("Error connecting - $@") unless defined $ssl;
$ssl->autoflush(1);
# Connect to the IMAP server in peek (i.e. don't set read flag) mode
my $imap = Mail::IMAPClient->new(
Debug => $debug,
Socket => $ssl,
Server => $hamserver,
User => $hamusername,
Password => $hampassword,
Peek => 1) or die "Cannot connect to $hamserver as $hamusername: $@";
$type = 'ham';
foreach my $folder (@{$folders{$type}}) {
print "\nLooking in $type folder $folder\n";
# Pick the folder
$imap->select($folder) or die "Cannot connect to $folder as $hamusername: $@";
# Enable peek mode
$imap->Peek(1);
# Fetch messages
my @mails = ($imap->seen(),$imap->unseen);
my $count = 0;
foreach my $id (@mails) {
$count++;
if($count < $skips) { next; }
print " Learning on $type message $id\n";
my $mail = $imap->message_string($id) or die "Cannot fetch $id in $folder: $@";
open SA, "| sa-learn -p /usr/mailcleaner/etc/mailscanner/spam.assassin.prefs.conf --siteconfigpath /usr/mailcleaner/share/spamassassin --no-sync --$type --single";
print SA $mail;
close SA;
# Bogofilter section
open BF, "| /usr/bogofilter/bin/bogofilter -n";
print BF $mail;
close BF;
if($deleteham) {
print "Deleting Ham (normal email) Message $id\n";
$imap->delete_message($id) or die "Cannot delete $id in $folder: $@";
}
if($deleteham) {
# Only expunge now, rather than on every message
$imap->expunge() or die "Cannot empty trash in $hamusername: $@";
}
}
}
print "\nNow rebuilding the Bayesian filters\n";
`sa-learn -p /usr/mailcleaner/etc/mailscanner/spam.assassin.prefs.conf --siteconfigpath /usr/mailcleaner/share/spamassassin --sync`;
$imap->close;
$ssl->close;
exit;