[Dovecot] mail messages moving between mailfolders

taras at elantech.ru taras at elantech.ru
Tue May 2 14:43:17 EEST 2006


Johannes Berg пишет:
> On Tue, 2006-05-02 at 11:27 +0200, Johannes Berg wrote:
>
>   
>> I do that, but it's much more userfriendly than multiple folders:
>>     
>
> Actually, I misunderstood what you're doing. But you can change my
> plugin to do exactly what you were looking for by simply doing some
> other action than calling dspam when a user moves messages.
>
> johannes
>   
I rebuild dspam for making strlen() of spam and not spam tags equivalen 
each to other.
I use only one spam folder, as you, but without any links or such things.
Here is script to understand what I'm doing:

----------
---------- BEGIN

use DBI;
use File::Find;

$user = "root";
$database = "mail";
$password = "****";

$spam_subfolder = ".SPAM";

$SENDER = "";

$SPAM_TAG = "SpamXXXX";
$HAM_TAG  = "Innocent";
$DSPAM_TAG = "X-DSPAM-Result:";

$curfile = "";

$ST = $IT = $SR = $IR = $AM = $AA = 0;

my $DBH = DBI->connect("DBI:mysql:$database", $user, $password) or die 
"I can't connect! Error: $DBI::errstr\n";

    my $sqlm = "SELECT email, homedir, maildir, uid, gid FROM 
postfix_users";
    my $sthm = $DBH->prepare($sqlm);
    $sthm->execute;
    my ($email, $homedir, $maildir, $uid, $gid);
    $sthm->bind_columns(undef, \($email, $homedir, $maildir, $uid, $gid));

    while($sthm->fetch){

    # find files in /.spam subfolder
    # and retrain dspam with mistake files

        my $spamdir = $homedir . "/" . $maildir . $spam_subfolder ;
        my $hamdir = $homedir . "/" . $maildir;

        $spamdir_cur = $spamdir . "/cur";
        $spamdir_new = $spamdir . "/new";
        $spamdir_tmp = $spamdir . "/tmp";

        $SENDER = $email;
       
        $ST = $IT = $SR = $IR = 0;
       
# SPAM       
        print "Training SPAM for user $email in $spamdir_cur...\n";       
        find(\&wanted_spam, $spamdir_cur);
        find(\&wanted_spam, $spamdir_new);       
       
# HAM       
        print "Training HAM for user $email in $hamdir\n";
        find(\&wanted_ham, $hamdir);   
       
        $AM = $ST+$IT;
            print "Stats for user $SENDER:\n";
        print "Total messages : " . $AM . "\n";
        print "Spam total: " . $ST . "\n";
        print "Innocent total: " . $IT . "\n";       
        print "HAM -> SPAM: " . $SR . "\n";       
        print "SPAM -> HAM: " . $IR . "\n";       
       
        $AA += $AM;
    }
   
    print "Total messages :" . $AA . "\n";
    print `date`;

$sthm->finish();
$DBH->disconnect();

#-----------------------------------------------------

sub wanted_spam {
   
    if ( -f $_) {
    $ST += 1;
    my $yes = 0;
    $curfile = $_;
    open("FD", "+<", $_) || die "Can't open file $_\n";
        flock FD, LOCK_EX || die "Can't lock file $_\n";
   
        while($str = <FD>){
            if($str =~ /$DSPAM_TAG/){
                $tag = $';
            if($tag =~ /$HAM_TAG/){           
                print "$HAM_TAG found: Rewriting!\n";
                print "File: $curfile\n";
                print "Dir: $File::Find::dir\n";               
                seek(FD, - (length($SPAM_TAG) + 2), 1);
                print FD " $SPAM_TAG";
                seek(FD, -1, 2);
                $yes = 1;
                $SR += 1;
            }else
            {
                if($tag =~ /" $SPAM_TAG"/){           
                print "$SPAM_TAG found: OK!\n";
                }
            }               
            }   
        }

        flock FD, LOCK_UN || die "Can't RElock file $_\n";   
            close(FD);               
        if($yes == 1){
        `cat '$curfile'| /usr/local/bin/dspam --user $SENDER 
--class=spam --source=error --deliver=`;   
        }
    }
}

sub wanted_ham {

    if("$File::Find::dir" ne "$spamdir_cur" && "$File::Find::dir" ne 
"$spamdir_new" && "$File::Find::dir" ne "$spamdir_tmp")   
    {
   
    if ( -f $_) {
    $IT += 1;
    my $yes = 0;
    $curfile = $_;
    open("FD", "+<", $_) || die "Can't open file $_\n";
        flock FD, LOCK_EX || die "Can't lock file $_\n";
   
        while($str = <FD>){
            if($str =~ /$DSPAM_TAG/){
                $tag = $';
            if($tag =~ /$SPAM_TAG/){           
                print "$SPAM_TAG found: Rewriting!\n";
                print "File: $curfile\n";
                print "Dir: $File::Find::dir\n";
                seek(FD, - (length($HAM_TAG) + 2), 1);
                print FD " $HAM_TAG";
                seek(FD, -1, 2);
                $yes = 1;
                $IR += 1;
            }else
            {
                if($tag =~ /" $HAM_TAG"/){           
                print "$HAM_TAG found: OK!\n";
                }
            }               
            }   
        }
        flock FD, LOCK_UN || die "Can't RElock file $_\n";   
            close(FD);               

        if($yes == 1){       
        `cat '$curfile' | /usr/local/bin/dspam --user $SENDER 
--class=innocent --source=error --deliver=`;
        }
    }
    }
}

--------- END
---------

I think, that easiest method to don't scan folders is simple log message 
moving between folders by IMAP server.
What do you think about this?

-- 
С уважением, Савчук Тарас
"ЭЛАНТЕК"
+7 (495) 589 68 81
+7 (926) 575 22 11
http://www.elantech.ru




More information about the dovecot mailing list