home

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 889299b6804134f6bcf124a566e20f143227f41e
parent 0c2518acf6fdacd2b1c97e474fdea7f54a60911a
Author: Vincent Demeester <vincent@sbr.pm>
Date:   Tue,  1 Dec 2020 10:29:38 +0100

users/vincent: import gmailctl stdlib

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Diffstat:
Musers/vincent/mails/default.nix | 1+
Ausers/vincent/mails/gmailctl.libsonnet | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/users/vincent/mails/default.nix b/users/vincent/mails/default.nix @@ -9,6 +9,7 @@ in sync = false; }; home.file.".gmailctl/config.jsonnet".source = ./config.jsonnet; + home.file.".gmailctl/gmailctl.jsonnet".source = ./gmailctl.libsonnet; xdg.configFile."nr/mails" = { text = builtins.toJSON [ diff --git a/users/vincent/mails/gmailctl.libsonnet b/users/vincent/mails/gmailctl.libsonnet @@ -0,0 +1,71 @@ +// gmailctl standard library +// +// This library contains utilities for common filter operations. + +{ + // chainFilters is a function that, given a list of rules, + // returns a new list where the rules are chained togheter, + // which means that they can be interpreted as a chain + // of "if elsif elsif". + // The result is basically a list of rules where each filter + // is modified by adding an AND with the negation of all the + // previous filters. + chainFilters(fs):: + // utility that given a rule it returns its negated filter. + local negate(r) = { not: r.filter }; + // recursive that goes trough all elements of arr + local aux(arr, i, negated, running) = + if i >= std.length(arr) then + running + else + // the new rule is an AND of: + // - the negation of all the previous rules + // - the current rule + local newr = { + filter: { + and: negated + [arr[i].filter], + }, + actions: arr[i].actions, + }; + aux(arr, i + 1, negated + [negate(arr[i])], running + [newr]) tailstrict; + + if std.length(fs) == 0 then [] + else aux(fs, 1, [negate(fs[0])], [fs[0]]), + + // directlyTo matches only email where the recipient is in the 'TO' + // field, not the 'CC' or 'BCC' ones. + directlyTo(recipient):: { + and: [ + { to: recipient }, + { not: { cc: recipient } }, + { not: { bcc: recipient } }, + ], + }, + + local extendWithParents(labels) = + local extend(p) = + local comps = std.split(p, '/'); + local aux(curr, rem) = + if std.length(rem) == 0 then + [curr] + else + aux(curr + '/' + rem[0], rem[1:]) + [curr]; + if std.length(comps) == 1 then [p] + else aux(comps[0], comps[1:]); + std.flattenArrays([extend(l) for l in labels]), + + // ruleLabels returns all the labels needed by the rule. + local ruleLabels(rule) = + if std.objectHas(rule.actions, 'labels') then + extendWithParents(rule.actions.labels) + else + [], + + // ruleLabels returns all the labels needed by the given rules. + // + // Note that no other properties, other than the name, are attached + // to the labels (i.e. the color). + rulesLabels(rules):: + local labels = std.uniq(std.sort(std.flattenArrays([ruleLabels(x) for x in rules]))); + [{ name: x } for x in labels], +}