tools/sieve-playground builds the vendored sieve-rs 0.7.3 (vnd.inbuxa.* names included) to WebAssembly, with a static page around it, for inbuxa Admin's Debug button on a Sieve script: until now that button sent the script to an outside site whose interpreter knows only upstream's extension names, so any script that requires vnd.inbuxa.* failed to compile there. Ported from the playground in the upstream sieve-rs repository's web/ directory (commit 549a2d57f7), which targets sieve-rs 1.x: - run.rs and handler.rs drive 0.7's event loop the way the server's delivery does, carrying on after a runtime error; llm_prompt compiles and answers false, as on a server without a model. - The expression functions are the server's own modules, included by path; tests fail if the list, ApplyString or the few functions copied from misc.rs/unicode.rs stop matching crates/common. - Built for wasm32-wasip1 rather than with wasm-bindgen: sieve-rs and mail-builder read the clock, which panics on wasm32-unknown-unknown. The page's worker answers the six WASI calls, giving the module the playground's current-time setting. shim/gethostname stands in for a crate with no WASI build. Nothing in vendor/ or crates/ changes. - The page carries no upstream names or links; storage keys and the samples are renamed to match. build.sh --admin <dir> stages the result into an inbuxa-admin checkout.
45 lines
1.2 KiB
Sieve
45 lines
1.2 KiB
Sieve
# inbuxa expressions and loops
|
|
#
|
|
# "vnd.inbuxa.expressions" adds "let" and "eval" with arithmetic,
|
|
# string functions and arrays. "vnd.inbuxa.while" adds loops. Both are
|
|
# inbuxa extensions to Sieve.
|
|
|
|
require ["variables", "editheader", "fileinto", "mailbox", "imap4flags",
|
|
"vnd.inbuxa.expressions", "vnd.inbuxa.while"];
|
|
|
|
# Header fields are available as values: the display name of the sender,
|
|
# falling back to the address when the name is empty.
|
|
let "sender" "header.from.name";
|
|
if eval "is_empty(sender)" {
|
|
let "sender" "header.from.addr";
|
|
}
|
|
addheader "X-Sender-Name" "${sender}";
|
|
|
|
let "recipients" "header.to:cc[*].addr[*]";
|
|
let "total" "count(recipients)";
|
|
let "shouting" "is_uppercase(header.subject)";
|
|
|
|
if eval "total > 3" {
|
|
addflag "$ManyRecipients";
|
|
}
|
|
|
|
let "i" "0";
|
|
let "domains" "''";
|
|
while "i < total" {
|
|
let "domain" "email_part(recipients[i], 'domain')";
|
|
let "domains" "domains + domain + ' '";
|
|
let "i" "i + 1";
|
|
}
|
|
addheader "X-Recipient-Domains" "${domains}";
|
|
|
|
if eval "shouting" {
|
|
addflag "$Shouting";
|
|
let "subject" "to_lowercase(header.subject)";
|
|
deleteheader "Subject";
|
|
addheader "Subject" "${subject}";
|
|
}
|
|
|
|
if eval "contains_ignore_case(header.subject, 'meeting')" {
|
|
fileinto :create "Calendar";
|
|
}
|