meli: adding the meli email client (#7111)

Meli email client integrated into the accounts.email.accouts settings.
This commit is contained in:
MunsMan 2025-05-29 05:30:10 +02:00 committed by GitHub
parent 7d2fcc864e
commit 13ed57aaa6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 274 additions and 0 deletions

View file

@ -591,6 +591,12 @@
github = "mtoohey31";
githubId = 36740602;
};
munsman = {
name = "Hendrik Munske";
email = "munsman.github@gmail.com";
github = "munsman";
githubId = 48153666;
};
n-hass = {
name = "Nicholas Hassan";
email = "nick@hassan.host";

View file

@ -186,6 +186,7 @@ let
./programs/matplotlib.nix
./programs/mbsync.nix
./programs/mcfly.nix
./programs/meli.nix
./programs/mercurial.nix
./programs/mergiraf.nix
./programs/micro.nix

197
modules/programs/meli.nix Normal file
View file

@ -0,0 +1,197 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
mkEnableOption
mkOption
types
mkIf
;
enabledAccounts = lib.attrsets.filterAttrs (
name: value: value.meli.enable or false
) config.accounts.email.accounts;
meliAccounts = (lib.attrsets.mapAttrs (name: value: (mkMeliAccounts name value)) enabledAccounts);
mkMeliAccounts = (
name: account: {
root_mailbox = "${config.accounts.email.maildirBasePath}/${account.maildir.path}";
format = "Maildir";
identity = account.address;
display_name = account.realName;
subscribed_mailboxes = account.meli.mailboxes;
send_mail = mkSmtp account;
mailboxes = account.meli.mailboxAliases;
}
);
mkSmtp = account: {
hostname = account.smtp.host;
port = account.smtp.port;
auth = {
type = "auto";
username = account.userName;
password = {
type = "command_eval";
value = lib.strings.concatStringsSep " " account.passwordCommand;
};
};
security = {
type =
if account.smtp.tls.enable or false then
if account.smtp.tls.useStartTls or false then "starttls" else "tls"
else
"none";
danger_accept_invalid_certs = false;
};
extensions = {
PIPELINING = true;
CHUNKING = true;
PRDR = true;
DSN_NOTIFY = "FAILURE";
};
};
in
{
meta.maintainers = with lib.hm.maintainers; [ munsman ];
options = {
programs.meli = {
enable = mkEnableOption "meli email client";
package = mkOption {
type = types.package;
default = pkgs.meli;
description = "meli package to use";
};
settings = mkOption {
type = types.submodule {
freeformType = (pkgs.formats.toml { }).type;
options = {
shortcuts = mkOption {
type = types.submodule {
options = {
general = mkOption {
type = types.attrsOf types.str;
default = { };
description = "general shortcut configuration";
example = {
scroll_up = "e";
scroll_down = "n";
next_page = "C-d";
};
};
composing = mkOption {
type = types.attrsOf types.str;
default = { };
description = "composing shortcut configuration";
example = {
edit = "m";
scroll_up = "e";
scroll_down = "n";
};
};
contact-list = mkOption {
type = types.attrsOf types.str;
default = { };
description = "contact-list shortcut configuration";
example = {
create_contact = "c";
edit_contact = "m";
};
};
listing = mkOption {
type = types.attrsOf types.str;
default = { };
description = "general shortcut configuration";
example = {
new_mail = "t";
set_seen = "s";
};
};
pager = mkOption {
type = types.attrsOf types.str;
default = { };
description = "general shortcut configuration";
example = {
scroll_up = "e";
scroll_down = "n";
};
};
};
};
default = { };
description = "Shortcut Settings";
};
};
};
default = { };
description = "Meli Configuration";
};
};
accounts.email.accounts = mkOption {
type = types.attrsOf (
types.submodule (
{ config, ... }:
{
options.meli = {
enable = mkEnableOption "the meli mail client for this account.\nRequires SMTP settings.";
mailboxes = mkOption {
type = with types; listOf str;
default = (
with config.folders;
[
inbox
sent
trash
drafts
]
);
example = [
"INBOX"
"Sent"
"Trash"
"Drafts"
];
description = "Mailboxes to show in meli";
};
mailboxAliases = mkOption {
type = with types; attrsOf attrs;
default = { };
example = {
"INBOX" = {
alias = "📥 Inbox";
};
"Sent" = {
alias = "📤 Sent";
};
};
description = "Folder display name";
};
};
}
)
);
};
};
config = mkIf config.programs.meli.enable {
home.packages = [ config.programs.meli.package ];
# Generate meli configuration from email accounts
xdg.configFile."meli/config.toml".source = (pkgs.formats.toml { }).generate "meli-config" (
{
accounts = meliAccounts;
}
// config.programs.meli.settings
);
};
}

View file

@ -240,6 +240,7 @@ import nmtSrc {
./modules/programs/lsd
./modules/programs/man
./modules/programs/mbsync
./modules/programs/meli
./modules/programs/mergiraf
./modules/programs/micro
./modules/programs/mise

View file

@ -0,0 +1 @@
{ meli = ./meli.nix; }

View file

@ -0,0 +1,40 @@
[accounts."hm@example.com"]
display_name = "H. M. Test"
format = "Maildir"
identity = "hm@example.com"
root_mailbox = "/home/hm-user/Mail/hm@example.com"
subscribed_mailboxes = ["Inbox", "Sent", "Trash", "Drafts"]
[accounts."hm@example.com".mailboxes]
[accounts."hm@example.com".send_mail]
hostname = "smtp.example.com"
port = 1848
[accounts."hm@example.com".send_mail.auth]
type = "auto"
username = "home.manager"
[accounts."hm@example.com".send_mail.auth.password]
type = "command_eval"
value = "password-command"
[accounts."hm@example.com".send_mail.extensions]
CHUNKING = true
DSN_NOTIFY = "FAILURE"
PIPELINING = true
PRDR = true
[accounts."hm@example.com".send_mail.security]
danger_accept_invalid_certs = false
type = "tls"
[shortcuts.composing]
[shortcuts.contact-list]
[shortcuts.general]
scroll_down = "j"
scroll_up = "k"
[shortcuts.listing]
[shortcuts.pager]

View file

@ -0,0 +1,28 @@
{
imports = [
../../accounts/email-test-accounts.nix
];
programs.meli = {
enable = true;
settings = {
shortcuts = {
general = {
scroll_up = "k";
scroll_down = "j";
};
};
};
};
accounts.email.accounts = {
"hm@example.com" = {
meli.enable = true;
smtp.port = 1848;
};
};
nmt.script = ''
assertFileExists home-files/.config/meli/config.toml
assertFileContent home-files/.config/meli/config.toml ${./expected.toml}
'';
}