Skip to content

Commit c2f6850

Browse files
committed
thunderbird: add message filters option
Add option to declare account-specific message filters.
1 parent fcac3d6 commit c2f6850

File tree

3 files changed

+124
-4
lines changed

3 files changed

+124
-4
lines changed

modules/programs/thunderbird.nix

+102-4
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,32 @@ let
155155
'') prefs)}
156156
${extraPrefs}
157157
'';
158+
159+
mkFilterToIniString = f:
160+
if f.text == null then
161+
''
162+
name="${f.name}"
163+
enabled="${if f.enabled then "yes" else "no"}"
164+
type="${f.type}"
165+
action="${f.action}"
166+
'' + optionalString (f.actionValue != null) ''
167+
actionValue="${f.actionValue}"
168+
'' + ''
169+
condition="${f.condition}"
170+
'' + optionalString (f.extraConfig != null) f.extraConfig
171+
else
172+
f.text;
173+
174+
mkFilterListToIni = filters:
175+
''
176+
version="9"
177+
logging="no"
178+
'' + concatStrings (map (f: mkFilterToIniString f) filters);
179+
180+
getEmailAccountsForProfile = profileName: accounts:
181+
(filter (a:
182+
a.thunderbird.profiles == [ ]
183+
|| any (p: p == profileName) a.thunderbird.profiles) accounts);
158184
in {
159185
meta.maintainers = with hm.maintainers; [ d-dervishi jkarlson ];
160186

@@ -408,6 +434,71 @@ in {
408434
argument is an automatically generated identifier.
409435
'';
410436
};
437+
438+
messageFilters = mkOption {
439+
type = with types;
440+
listOf (submodule {
441+
options = {
442+
name = mkOption {
443+
type = str;
444+
description = "Name for the filter.";
445+
};
446+
enabled = mkOption {
447+
type = bool;
448+
default = true;
449+
description = "Whether this filter is currently active.";
450+
};
451+
type = mkOption {
452+
type = str;
453+
description = "Type for this filter.";
454+
};
455+
action = mkOption {
456+
type = str;
457+
description = "Action to perform on matched messages.";
458+
};
459+
actionValue = mkOption {
460+
type = nullOr str;
461+
default = null;
462+
description =
463+
"Argument passed to the filter action, e.g. a folder path.";
464+
};
465+
condition = mkOption {
466+
type = str;
467+
description = "Condition to match messages against.";
468+
};
469+
extraConfig = mkOption {
470+
type = nullOr str;
471+
default = null;
472+
description = "Extra settings to apply to the filter";
473+
};
474+
text = mkOption {
475+
type = nullOr str;
476+
default = null;
477+
description = ''
478+
The raw text of the filter.
479+
Note that this will override all other options.
480+
'';
481+
};
482+
};
483+
});
484+
default = [ ];
485+
defaultText = literalExpression "[ ]";
486+
example = literalExpression ''
487+
[
488+
{
489+
name = "Mark as Read on Archive";
490+
enabled = true;
491+
type = "128";
492+
action = "Mark read";
493+
condition = "ALL";
494+
}
495+
]
496+
'';
497+
description = ''
498+
List of message filters to add to this Thunderbird account
499+
configuration.
500+
'';
501+
};
411502
};
412503
});
413504
};
@@ -463,9 +554,7 @@ in {
463554
mkIf (profile.userContent != "") { text = profile.userContent; };
464555

465556
"${thunderbirdProfilesPath}/${name}/user.js" = let
466-
emailAccounts = filter (a:
467-
a.thunderbird.profiles == [ ]
468-
|| any (p: p == name) a.thunderbird.profiles) enabledAccountsWithId;
557+
emailAccounts = getEmailAccountsForProfile name enabledAccountsWithId;
469558

470559
smtp = filter (a: a.smtp != null) emailAccounts;
471560

@@ -514,6 +603,15 @@ in {
514603
recursive = true;
515604
force = true;
516605
};
517-
}));
606+
}) ++ (mapAttrsToList (name: profile:
607+
let
608+
emailAccountsWithFilters =
609+
(filter (a: a.thunderbird.messageFilters != [ ])
610+
(getEmailAccountsForProfile name enabledAccountsWithId));
611+
in (builtins.listToAttrs (map (a: {
612+
name =
613+
"${thunderbirdConfigPath}/${name}/ImapMail/${a.id}/msgFilterRules.dat";
614+
value = { text = mkFilterListToIni a.thunderbird.messageFilters; };
615+
}) emailAccountsWithFilters))) cfg.profiles));
518616
};
519617
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
version="9"
2+
logging="no"
3+
name="Mark as Read on Archive"
4+
enabled="yes"
5+
type="128"
6+
action="Mark read"
7+
condition="ALL"

tests/modules/programs/thunderbird/thunderbird.nix

+15
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
thunderbird = {
77
enable = true;
88
profiles = [ "first" ];
9+
messageFilters = [{
10+
name = "Mark as Read on Archive";
11+
enabled = true;
12+
type = "128";
13+
action = "Mark read";
14+
condition = "ALL";
15+
}];
916
};
1017

1118
aliases = [ "[email protected]" ];
@@ -99,5 +106,13 @@
99106
assertFileExists home-files/${profilesDir}/first/chrome/userContent.css
100107
assertFileContent home-files/${profilesDir}/first/chrome/userContent.css \
101108
<(echo "* { color: red !important; }")
109+
110+
assertFileExists home-files/.thunderbird/first/ImapMail/${
111+
builtins.hashString "sha256" "[email protected]"
112+
}/msgFilterRules.dat
113+
assertFileContent home-files/.thunderbird/first/ImapMail/${
114+
builtins.hashString "sha256" "[email protected]"
115+
}/msgFilterRules.dat \
116+
${./thunderbird-expected-msgFilterRules.dat}
102117
'';
103118
}

0 commit comments

Comments
 (0)