I found it's quite convenient to prepare filters in Thunderbird. However there's one minor inconvenience - it does not store filters serverside (yes, I'm using outlook/exchange at work) which makes all your pretty organised workspace bound to the Thunderbird client.
I think this is unacceptable, hence written this small script, which does exactly what I need - converts my thunderbird filter rules into procmail rc recipes. Definitely it contains only those parts of filter syntax I am using so do not expect it be full through-out converter. To convert the rules - locate your filter-set (use locate msgFilterRules.dat
or find .thunderbird -name '*msgFilterRules*'
to find it) and execute cat path/to/msgFilterRules.dat | ./tbf2pmrc >> .procmailrc
tbf2pmrc: #!/usr/bin/perl -w use strict; my ($name,%condition,%action,%type,%enabled,$an,@rn); # Action map - actions are reverse sorted when recipe is printed # Define new actions here with correct priority. # Priority 2 - move to the folder - stops flow thus should not change my %am=("Stop execution" => 1, "Move to folder" => 2, "Forward" => 3, "Copy to folder" => 4, "AddTag" => 10, "Delete" => 9999); # TODO: Action 1 - stop execution - save to inbox? # Use maildit format? my $MD=1; while(<STDIN>) { chomp; if(/^condition=\"OR (.*)\"/){ my @o; for my$c(split(' OR ',$1)){ $c=~s/^\((.)(.+)\)/@{[uc($1)]}$2/; $c=~s/([\[\](){}.+])/\\$1/omg; $c=~s/\*/.*/omg; $c=~s/All addresses/(From|To|Cc|Bcc)/; $c=~s/,(contains|is),/:\.\*/; push@o,"^$c.*"; } $condition{$name}=join("|\\\n ",@o); } elsif(/^condition=\"AND \(([^)]+)\)\"/){ my $g=$1; $g=~s/(.)(.+)/@{[uc($1)]}$2/; $g=~s/([\[\](){}.+])/\\$1/omg; $g=~s/All addresses/(From|To|Cc|Bcc)/; $g=~s/,(contains|is),/:\.\*/; $condition{$name}="^$g.*"; } elsif(/^action=\"(.+)\"/) { $an=$am{$1}; $an=0 unless($an); # throw away undefined actions } elsif(/^actionValue=\"(.+)\"/){ if(exists($action{$name}->{$an})) { push(@{$action{$name}->{$an}},$1); } else { $action{$name}->{$an}=[$1]; } } elsif(/^type=\"(.+)\"/){ $type{$name}=$1; } elsif(/^enabled=\"(.+)\"/){ $enabled{$name}=$1; push(@rn,$name) if($1 eq 'yes'); } elsif(/^name=\"(.+)\"/){ $name=$1; } } foreach my$n(@rn){ print":0:\n* ".$condition{$n}."\n{\n"; for$an(sort{$b<=>$a}(keys(%{$action{$n}}))) { last if($an<2); # Action 1 - stop processing rules if($an == 2 || $an == 4) { # Store mail for my$d(@{$action{$n}->{$an}}){ my $m=$d; $m=~s!imap://[^/]+/!!; $m=~y!/!.!; print(":0"); print(" c") if($an > 2); print(":\n"); print(".$m"); print('/') if($MD); print("\n\n"); } } elsif($an == 3) { # Forward - stops execution print(":0:\n"); print("! ".$action{$n}->{$an}->[0]); print("\n\n"); } elsif($an == 10) { # Add tag my$t = join('', map {"-I 'X-Add-tag: $_' "} @{$action{$n}->{$an}}); print(":0 f:\n"); print("| formail $t\n\n"); } elsif($an == 9999) { # Delete print(":0:\n/dev/null\n\n"); last; # Not processing any rules if Delete } } print("}\n\n"); }Link... Mon Jun 11 03:11:17 2012 Upd.: Sat Feb 9 14:52:57 2013