Generalized looping possible in pigeonhole sieve?
I'm struggling to achieve the kind of filtering with sieve that I was able to do with procmail.
TL;DR
I'd like a way to loop through a set of (address, destination) pairs in sieve so that I can maintain the (address, destination) pairs in one place and not have to explicitly write scores of nearly identical
[...]
if address :matches ["From", "Sender", "To", "Cc"] "address53" { fileinto "destination53" }
if address :matches ["From", "Sender", "To", "Cc"] "address54" { fileinto "destination54" }
[...]
Longer:
I've been using a table-based dispatch approach with procmail for years and it was working reasonably well.
The approach uses list of pairs of address and destination boxes and doing a lookup based on the message to be delivered. With procmail, I collected the list of addresses and passed them to external scripts to do the lookup.
If I just had a dozen boxes that I deal with, that would be straightforward to implement and maintain in sieve. As the list is an order of magnitude greater than that, maintaining the list of pairs in an external file and programmatically looping through it is a lot easier.
I've looked at vnd.dovecot.execute and it certainly can return a destination box name given the input information.
Unfortunately, the construct of (for example)
address :matches "To" "*"'
only returns the first address, not the list of addresses.
I can't see a good way to get all the addressees from sieve to pass to the external program. If I have to pass the message (or at least the interesting headers) to the external program and then parse the address list myself, then I'm nearly all the way to just using a full-on external program to parse the whole message.
While I'm not adverse to writing the whole thing in Python (or the like) and just using sieve as a thin shell, I'd like to make sure I'm not missing something in sieve.
One way to achieve this would be to be able to loop through the pairs and using variable substitution for each iteration. I haven't seen anything in Dovecot Pigeonhole sieve that allows this.
If you have any ideas on how to harness sieve for this, I'd appreciate it!
Jeff
Sieve EXPLICITLY does NOT have a looping construct.
On Thu, Nov 17, 2016 at 4:42 PM, Jeff Kletsky dovecot@allycomm.com wrote:
I'm struggling to achieve the kind of filtering with sieve that I was able to do with procmail.
TL;DR
I'd like a way to loop through a set of (address, destination) pairs in sieve so that I can maintain the (address, destination) pairs in one place and not have to explicitly write scores of nearly identical
[...]
if address :matches ["From", "Sender", "To", "Cc"] "address53" { fileinto "destination53" }
if address :matches ["From", "Sender", "To", "Cc"] "address54" { fileinto "destination54" }
[...]
Longer:
I've been using a table-based dispatch approach with procmail for years and it was working reasonably well.
The approach uses list of pairs of address and destination boxes and doing a lookup based on the message to be delivered. With procmail, I collected the list of addresses and passed them to external scripts to do the lookup.
If I just had a dozen boxes that I deal with, that would be straightforward to implement and maintain in sieve. As the list is an order of magnitude greater than that, maintaining the list of pairs in an external file and programmatically looping through it is a lot easier.
I've looked at vnd.dovecot.execute and it certainly can return a destination box name given the input information.
Unfortunately, the construct of (for example)
address :matches "To" "*"'
only returns the first address, not the list of addresses.
I can't see a good way to get all the addressees from sieve to pass to the external program. If I have to pass the message (or at least the interesting headers) to the external program and then parse the address list myself, then I'm nearly all the way to just using a full-on external program to parse the whole message.
While I'm not adverse to writing the whole thing in Python (or the like) and just using sieve as a thin shell, I'd like to make sure I'm not missing something in sieve.
One way to achieve this would be to be able to loop through the pairs and using variable substitution for each iteration. I haven't seen anything in Dovecot Pigeonhole sieve that allows this.
If you have any ideas on how to harness sieve for this, I'd appreciate it!
Jeff
-- Larry Rosenman http://www.lerctr.org/~ler Phone: +1 214-642-9640 (c) E-Mail: larryrtx@gmail.com US Mail: 17716 Limpia Crk, Round Rock, TX 78664-7281
On Thu, Nov 17, 2016 at 02:42:31PM -0800, Jeff Kletsky wrote:
I'm struggling to achieve the kind of filtering with sieve that I was able to do with procmail.
A couple of options that I can think of:
If the address is sufficiently like the folder name, you can use sieve's regex capabilities. For example, I convert addresses such as "user+folder@example.com" to "Tagged/Folder" using:
require [ "fileinto", "mailbox", "subaddress", "variables", "regex",
"envelope"];
if envelope :detail :regex "to" "(.+)" {
set :upperfirst :lower "detail" "${1}";
fileinto :create "Tagged/${detail}";
stop;
}
Another alternative is, if your map of addresses is complex, but doesn't change very often, use a script (such as a Makefile) to generate the sieve script from the map. Then, next time you update the map, you re-run the script which re-writes the sieve file.
TL;DR
I'd like a way to loop through a set of (address, destination) pairs in sieve so that I can maintain the (address, destination) pairs in one place and not have to explicitly write scores of nearly identical
[...]
if address :matches ["From", "Sender", "To", "Cc"] "address53" { fileinto "destination53" }
if address :matches ["From", "Sender", "To", "Cc"] "address54" { fileinto "destination54" }
[...]
Longer:
I've been using a table-based dispatch approach with procmail for years and it was working reasonably well.
The approach uses list of pairs of address and destination boxes and doing a lookup based on the message to be delivered. With procmail, I collected the list of addresses and passed them to external scripts to do the lookup.
If I just had a dozen boxes that I deal with, that would be straightforward to implement and maintain in sieve. As the list is an order of magnitude greater than that, maintaining the list of pairs in an external file and programmatically looping through it is a lot easier.
I've looked at vnd.dovecot.execute and it certainly can return a destination box name given the input information.
Unfortunately, the construct of (for example)
address :matches "To" "*"'
only returns the first address, not the list of addresses.
I can't see a good way to get all the addressees from sieve to pass to the external program. If I have to pass the message (or at least the interesting headers) to the external program and then parse the address list myself, then I'm nearly all the way to just using a full-on external program to parse the whole message.
While I'm not adverse to writing the whole thing in Python (or the like) and just using sieve as a thin shell, I'd like to make sure I'm not missing something in sieve.
One way to achieve this would be to be able to loop through the pairs and using variable substitution for each iteration. I haven't seen anything in Dovecot Pigeonhole sieve that allows this.
If you have any ideas on how to harness sieve for this, I'd appreciate it!
Jeff
-- For more information, please reread.
participants (3)
-
Darac Marjal
-
Jeff Kletsky
-
Larry Rosenman