On Fri, Sep 12, 2014 at 10:25:19PM +0400, Lev Serebryakov wrote:
> Hello, Dovecot.
> 
> 
>  Is it possible to write one rule in sieve, which will:
> 
> (1) Trigger on any message with "List-Id" header
> 
> AND
> 
> (2) Put this message to folder with name build from content of "List-Id"
> header, in such way, that message with List-Id
> 
> List-Id: This is decription of list <list-name.host.org>
> 
>  will be put into folder "org.host.list-name" where "." is namespace
> separator (so, such folders will be shown as hierarchy in mail client)?
> 
>  I don't want to write ~50 rules by hands and add new ones from time to
> time.
> 
>  I'm speaking about dovecot/pigeonhole sieve implementation, of course. All
>  examples on net shows only manual one-rule-per-list approach :(


Not one rule, but I use the following script to filter mailing lists
into folders. It handles most mailing list types and, for consistency,
the folder name is case-folded to title case.

##
require [ "regex", "variables", "fileinto", "envelope", "mailbox", "imap4flags" 
];

# Mailinglist Killfile
if anyof (header :contains "from" "unwan...@example.com",
          header :contains "from" "spam...@example.net",
          header :contains "from" "tr...@example.org"){
        discard;
        stop;
}

if anyof (header :contains "x-spam-flag" "yes",
          allof (header :regex "X-DSPAM-Result" "^(Spam|Virus|Bl[ao]cklisted)$",
                 not header :contains "X-DSPAM-Reclassified" "Innocent")){
        # Spam goes into the spam folder
        setflag "\\Seen";
        fileinto :create "spam";
        stop;
}

# split out the various list forms
# Mailman & other lists using list-id
if exists "list-id" {
    if header :regex "list-id" "<([a-z_0-9-]+)[.@]" {
        set :lower "listname" "${1}";
        fileinto :create "${listname}";
    } else {
        if header :regex "list-id" "^\\s*<?([a-z_0-9-]+)[.@]" {
            set :lower "listname" "${1}";
            fileinto :create "${listname}";
        } else {
            keep;
        }
    }
    stop;}
# Listar and mailman like
elsif exists "x-list-id" {
    if header :regex "x-list-id" "<([a-z_0-9-]+)\\\\." {
        set :lower "listname" "${1}";
        fileinto :create "${listname}";
    } else {
        keep;
    }
    stop;}
# Ezmlm
elsif exists "mailing-list" {
    if header :regex "mailing-list" "([a-z_0-9-]+)@" {
        set :lower "listname" "${1}";
        fileinto :create "${listname}";
    } else {
        keep;
    }
    stop;}
# York lists service
elsif exists "x-mailing-list" {
    if header :regex "x-mailing-list" "^\\s*([a-z_0-9-]+)@?" {
        set :lower "listname" "${1}";
        fileinto :create "${listname}";
    } else {
        keep;
    }
    stop;}
# Smartlist
elsif exists "x-loop" {
        if header :regex "x-loop" "^\\s*(a-z_0-9-]+)@?" {
                set :lower "listname" "${1}";
                fileinto :create "${listname}";
        } else {
            keep;
        }
    stop;}
# poorly identified
elsif envelope :contains "from" "owner-" {
    if envelope :regex "from" "owner-([a-z_0-9-]+)-outgoing@" {
        set :lower "listname" "${1}";
        fileinto :create "${listname}";
    } elsif envelope :regex "from" "owner-([a-z_0-9-]+)@" {
        set :lower "listname" "${1}";
        fileinto :create "${listname}";
    } elsif header :regex "Sender" "owner-([a-z_0-9-]+)@" {
        set :lower "listname" "${1}";
        fileinto :create "${listname}";
    } else {
        keep;
    }
    stop;}
# other poorly identified
elsif  envelope :contains "from" "-request" {
    if envelope :regex "from" "([a-z_0-9-]+)-request@" {
        set :lower "listname" "${1}";
        fileinto :create "${listname}";
    } else {
        keep;
    }
    stop;
}

Attachment: signature.asc
Description: Digital signature

Reply via email to