From 13ed57aaa679253d7989db21f4581ae85b2167fa Mon Sep 17 00:00:00 2001 From: MunsMan <48153666+MunsMan@users.noreply.github.com> Date: Thu, 29 May 2025 05:30:10 +0200 Subject: [PATCH] meli: adding the meli email client (#7111) Meli email client integrated into the accounts.email.accouts settings. --- modules/lib/maintainers.nix | 6 + modules/modules.nix | 1 + modules/programs/meli.nix | 197 ++++++++++++++++++++++ tests/default.nix | 1 + tests/modules/programs/meli/default.nix | 1 + tests/modules/programs/meli/expected.toml | 40 +++++ tests/modules/programs/meli/meli.nix | 28 +++ 7 files changed, 274 insertions(+) create mode 100644 modules/programs/meli.nix create mode 100644 tests/modules/programs/meli/default.nix create mode 100644 tests/modules/programs/meli/expected.toml create mode 100644 tests/modules/programs/meli/meli.nix diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 42020b63..8f401039 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -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"; diff --git a/modules/modules.nix b/modules/modules.nix index e3e9ac19..99b32b8f 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -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 diff --git a/modules/programs/meli.nix b/modules/programs/meli.nix new file mode 100644 index 00000000..4abb9a46 --- /dev/null +++ b/modules/programs/meli.nix @@ -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 + ); + + }; +} diff --git a/tests/default.nix b/tests/default.nix index 44c7da96..3af9c443 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -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 diff --git a/tests/modules/programs/meli/default.nix b/tests/modules/programs/meli/default.nix new file mode 100644 index 00000000..9585b439 --- /dev/null +++ b/tests/modules/programs/meli/default.nix @@ -0,0 +1 @@ +{ meli = ./meli.nix; } diff --git a/tests/modules/programs/meli/expected.toml b/tests/modules/programs/meli/expected.toml new file mode 100644 index 00000000..e6a55a85 --- /dev/null +++ b/tests/modules/programs/meli/expected.toml @@ -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] diff --git a/tests/modules/programs/meli/meli.nix b/tests/modules/programs/meli/meli.nix new file mode 100644 index 00000000..d4e93723 --- /dev/null +++ b/tests/modules/programs/meli/meli.nix @@ -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} + ''; +}