2021-06-26 22:29:42 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
let
|
|
|
|
# aliases
|
|
|
|
inherit (config.programs) himalaya;
|
2021-06-26 22:29:42 +00:00
|
|
|
tomlFormat = pkgs.formats.toml { };
|
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
# attrs util that removes entries containing a null value
|
|
|
|
compactAttrs = lib.filterAttrs (_: val: !isNull val);
|
|
|
|
|
2023-07-03 18:30:11 +00:00
|
|
|
# Needed for notmuch config, because the DB is here, and not in each account's dir
|
|
|
|
maildirBasePath = config.accounts.email.maildirBasePath;
|
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
# make a himalaya config from a home-manager email account config
|
|
|
|
mkAccountConfig = _: account:
|
|
|
|
let
|
2023-07-03 18:30:11 +00:00
|
|
|
# Use notmuch if it's enabled, otherwise fallback to IMAP then maildir
|
|
|
|
# Maildir is always set, so there's no easy way to detect if it's being used
|
|
|
|
notmuchEnabled = account.notmuch.enable;
|
|
|
|
imapEnabled = !isNull account.imap && !notmuchEnabled;
|
|
|
|
maildirEnabled = !isNull account.maildir && !imapEnabled
|
|
|
|
&& !notmuchEnabled;
|
2023-06-21 08:59:29 +00:00
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
globalConfig = {
|
2021-06-26 22:29:42 +00:00
|
|
|
email = account.address;
|
2022-10-16 08:25:31 +00:00
|
|
|
display-name = account.realName;
|
2021-06-26 22:29:42 +00:00
|
|
|
default = account.primary;
|
2023-05-04 10:28:08 +00:00
|
|
|
folder-aliases = {
|
2022-05-30 19:04:13 +00:00
|
|
|
inbox = account.folders.inbox;
|
|
|
|
sent = account.folders.sent;
|
2023-05-04 10:28:08 +00:00
|
|
|
drafts = account.folders.drafts;
|
|
|
|
trash = account.folders.trash;
|
2022-05-30 19:04:13 +00:00
|
|
|
};
|
2023-05-04 10:28:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
signatureConfig =
|
|
|
|
lib.optionalAttrs (account.signature.showSignature == "append") {
|
|
|
|
# TODO: signature cannot be attached yet
|
|
|
|
# https://todo.sr.ht/~soywod/himalaya/27
|
|
|
|
signature = account.signature.text;
|
|
|
|
signature-delim = account.signature.delimiter;
|
|
|
|
};
|
|
|
|
|
2023-06-21 08:59:29 +00:00
|
|
|
imapConfig = lib.optionalAttrs imapEnabled (compactAttrs {
|
2023-05-04 10:28:08 +00:00
|
|
|
backend = "imap";
|
2021-06-26 22:29:42 +00:00
|
|
|
imap-host = account.imap.host;
|
|
|
|
imap-port = account.imap.port;
|
2023-05-04 10:28:08 +00:00
|
|
|
imap-ssl = account.imap.tls.enable;
|
2021-06-26 22:29:42 +00:00
|
|
|
imap-starttls = account.imap.tls.useStartTls;
|
2023-05-04 10:28:08 +00:00
|
|
|
imap-login = account.userName;
|
2023-06-21 08:59:29 +00:00
|
|
|
imap-auth = "passwd";
|
|
|
|
imap-passwd.cmd = builtins.concatStringsSep " " account.passwordCommand;
|
2023-05-04 10:28:08 +00:00
|
|
|
});
|
|
|
|
|
2023-06-21 08:59:29 +00:00
|
|
|
maildirConfig = lib.optionalAttrs maildirEnabled (compactAttrs {
|
|
|
|
backend = "maildir";
|
|
|
|
maildir-root-dir = account.maildir.absPath;
|
|
|
|
});
|
|
|
|
|
|
|
|
notmuchConfig = lib.optionalAttrs notmuchEnabled (compactAttrs {
|
|
|
|
backend = "notmuch";
|
2023-07-03 18:30:11 +00:00
|
|
|
notmuch-db-path = maildirBasePath;
|
2023-06-21 08:59:29 +00:00
|
|
|
});
|
2023-05-04 10:28:08 +00:00
|
|
|
|
|
|
|
smtpConfig = lib.optionalAttrs (!isNull account.smtp) (compactAttrs {
|
|
|
|
sender = "smtp";
|
2021-06-26 22:29:42 +00:00
|
|
|
smtp-host = account.smtp.host;
|
|
|
|
smtp-port = account.smtp.port;
|
2023-05-04 10:28:08 +00:00
|
|
|
smtp-ssl = account.smtp.tls.enable;
|
2022-02-21 21:32:32 +00:00
|
|
|
smtp-starttls = account.smtp.tls.useStartTls;
|
2023-05-04 10:28:08 +00:00
|
|
|
smtp-login = account.userName;
|
2023-06-21 08:59:29 +00:00
|
|
|
smtp-auth = "passwd";
|
|
|
|
smtp-passwd.cmd = builtins.concatStringsSep " " account.passwordCommand;
|
2023-05-04 10:28:08 +00:00
|
|
|
});
|
2021-06-26 22:29:42 +00:00
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
sendmailConfig =
|
2023-06-21 08:59:29 +00:00
|
|
|
lib.optionalAttrs (isNull account.smtp && !isNull account.msmtp) {
|
|
|
|
sender = "sendmail";
|
|
|
|
sendmail-cmd = "${pkgs.msmtp}/bin/msmtp";
|
|
|
|
};
|
2021-06-26 22:29:42 +00:00
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
config = globalConfig // signatureConfig // imapConfig // maildirConfig
|
2023-06-21 08:59:29 +00:00
|
|
|
// notmuchConfig // smtpConfig // sendmailConfig;
|
2023-05-04 10:28:08 +00:00
|
|
|
|
|
|
|
in lib.recursiveUpdate config account.himalaya.settings;
|
|
|
|
|
|
|
|
# make a systemd service config from a name and a description
|
|
|
|
mkServiceConfig = name: desc:
|
|
|
|
let
|
|
|
|
inherit (config.services."himalaya-${name}") enable environment settings;
|
|
|
|
optionalArg = key:
|
|
|
|
if (key ? settings && !isNull settings."${key}") then
|
|
|
|
[ "--${key} ${settings."${key}"}" ]
|
|
|
|
else
|
|
|
|
[ ];
|
|
|
|
in {
|
|
|
|
"himalaya-${name}" = lib.mkIf enable {
|
|
|
|
Unit = {
|
|
|
|
Description = desc;
|
|
|
|
After = [ "network.target" ];
|
|
|
|
};
|
|
|
|
Install = { WantedBy = [ "default.target" ]; };
|
|
|
|
Service = {
|
|
|
|
ExecStart = lib.concatStringsSep " "
|
|
|
|
([ "${himalaya.package}/bin/himalaya" ] ++ optionalArg "account"
|
|
|
|
++ [ name ] ++ optionalArg "keepalive");
|
|
|
|
ExecSearchPath = "/bin";
|
|
|
|
Environment =
|
|
|
|
lib.mapAttrsToList (key: val: "${key}=${val}") environment;
|
|
|
|
Restart = "always";
|
|
|
|
RestartSec = 10;
|
|
|
|
};
|
2021-06-26 22:29:42 +00:00
|
|
|
};
|
2023-05-04 10:28:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
in {
|
|
|
|
meta.maintainers = with lib.hm.maintainers; [ soywod toastal ];
|
2021-06-26 22:29:42 +00:00
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
options = {
|
|
|
|
programs.himalaya = {
|
2023-06-30 23:06:56 +00:00
|
|
|
enable = lib.mkEnableOption "the Himalaya email client";
|
2023-05-04 10:28:08 +00:00
|
|
|
package = lib.mkPackageOption pkgs "himalaya" { };
|
|
|
|
settings = lib.mkOption {
|
|
|
|
type = lib.types.submodule { freeformType = tomlFormat.type; };
|
2021-06-26 22:29:42 +00:00
|
|
|
default = { };
|
|
|
|
description = ''
|
2023-05-04 10:28:08 +00:00
|
|
|
Himalaya global configuration.
|
|
|
|
See <link xlink:href="https://pimalaya.org/himalaya/cli/configuration/global.html"/> for supported values.
|
2021-06-26 22:29:42 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
services = {
|
|
|
|
himalaya-notify = {
|
2023-06-30 23:06:56 +00:00
|
|
|
enable = lib.mkEnableOption "the Himalaya new emails notifier service";
|
2023-05-04 10:28:08 +00:00
|
|
|
|
|
|
|
environment = lib.mkOption {
|
|
|
|
type = with lib.types; attrsOf str;
|
|
|
|
default = { };
|
|
|
|
example = lib.literalExpression ''
|
|
|
|
{
|
|
|
|
"PASSWORD_STORE_DIR" = "~/.password-store";
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
Extra environment variables to be exported in the service.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
settings = {
|
|
|
|
account = lib.mkOption {
|
|
|
|
type = with lib.types; nullOr str;
|
|
|
|
default = null;
|
|
|
|
example = "gmail";
|
|
|
|
description = ''
|
|
|
|
Name of the account the notifier should be started for. If
|
|
|
|
no account is given, the default one is used.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
keepalive = lib.mkOption {
|
|
|
|
type = with lib.types; nullOr int;
|
|
|
|
default = null;
|
|
|
|
example = "500";
|
|
|
|
description = ''
|
|
|
|
Notifier lifetime of the IDLE session (in seconds).
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
himalaya-watch = {
|
2023-06-30 23:06:56 +00:00
|
|
|
enable =
|
|
|
|
lib.mkEnableOption "the Himalaya folder changes watcher service";
|
2023-05-04 10:28:08 +00:00
|
|
|
|
|
|
|
environment = lib.mkOption {
|
|
|
|
type = with lib.types; attrsOf str;
|
|
|
|
default = { };
|
|
|
|
example = lib.literalExpression ''
|
|
|
|
{
|
|
|
|
"PASSWORD_STORE_DIR" = "~/.password-store";
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
Extra environment variables to be exported in the service.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
settings = {
|
|
|
|
account = lib.mkOption {
|
|
|
|
type = with lib.types; nullOr str;
|
|
|
|
default = null;
|
|
|
|
example = "gmail";
|
|
|
|
description = ''
|
|
|
|
Name of the account the watcher should be started for. If
|
|
|
|
no account is given, the default one is used.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
keepalive = lib.mkOption {
|
|
|
|
type = with lib.types; nullOr int;
|
|
|
|
default = null;
|
|
|
|
example = "500";
|
|
|
|
description = ''
|
|
|
|
Watcher lifetime of the IDLE session (in seconds).
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
accounts.email.accounts = lib.mkOption {
|
|
|
|
type = lib.types.attrsOf (lib.types.submodule {
|
|
|
|
options.himalaya = {
|
2023-06-30 23:06:56 +00:00
|
|
|
enable = lib.mkEnableOption "Himalaya for this email account";
|
2023-05-04 10:28:08 +00:00
|
|
|
|
|
|
|
# TODO: remove me for the next release
|
|
|
|
backend = lib.mkOption {
|
|
|
|
type = with lib.types; nullOr str;
|
|
|
|
default = null;
|
2023-06-30 22:35:51 +00:00
|
|
|
description = lib.mdDoc ''
|
|
|
|
Specifying {option}`accounts.email.accounts.*.himalaya.backend` is deprecated,
|
|
|
|
set {option}`accounts.email.accounts.*.himalaya.settings.backend` instead.
|
2021-06-26 22:29:42 +00:00
|
|
|
'';
|
2023-05-04 10:28:08 +00:00
|
|
|
};
|
2021-06-26 22:29:42 +00:00
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
# TODO: remove me for the next release
|
|
|
|
sender = lib.mkOption {
|
|
|
|
type = with lib.types; nullOr str;
|
2023-06-30 22:35:51 +00:00
|
|
|
description = lib.mdDoc ''
|
|
|
|
Specifying {option}`accounts.email.accounts.*.himalaya.sender` is deprecated,
|
|
|
|
set {option}'accounts.email.accounts.*.himalaya.settings.sender' instead.
|
2023-05-04 10:28:08 +00:00
|
|
|
'';
|
2021-06-26 22:29:42 +00:00
|
|
|
};
|
2023-05-04 10:28:08 +00:00
|
|
|
|
|
|
|
settings = lib.mkOption {
|
|
|
|
type = lib.types.submodule { freeformType = tomlFormat.type; };
|
|
|
|
default = { };
|
|
|
|
description = ''
|
|
|
|
Himalaya configuration for this email account.
|
|
|
|
See <link xlink:href="https://pimalaya.org/himalaya/cli/configuration/account.html"/> for supported values.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
});
|
2021-06-26 22:29:42 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
config = lib.mkIf himalaya.enable {
|
|
|
|
home.packages = [ himalaya.package ];
|
|
|
|
|
|
|
|
xdg.configFile."himalaya/config.toml".source = let
|
|
|
|
enabledAccounts = lib.filterAttrs (_: account: account.himalaya.enable)
|
|
|
|
config.accounts.email.accounts;
|
|
|
|
accountsConfig = lib.mapAttrs mkAccountConfig enabledAccounts;
|
|
|
|
globalConfig = compactAttrs himalaya.settings;
|
|
|
|
allConfig = globalConfig // accountsConfig;
|
|
|
|
in tomlFormat.generate "himalaya-config.toml" allConfig;
|
|
|
|
|
|
|
|
systemd.user.services = { }
|
|
|
|
// mkServiceConfig "notify" "Himalaya new emails notifier service"
|
|
|
|
// mkServiceConfig "watch" "Himalaya folder changes watcher service";
|
2021-06-26 22:29:42 +00:00
|
|
|
|
2023-05-04 10:28:08 +00:00
|
|
|
# TODO: remove me for the next release
|
|
|
|
warnings = (lib.optional ("backend" ? himalaya && !isNull himalaya.backend)
|
|
|
|
"Specifying 'accounts.email.accounts.*.himalaya.backend' is deprecated, set 'accounts.email.accounts.*.himalaya.settings.backend' instead")
|
|
|
|
++ (lib.optional ("sender" ? himalaya && !isNull himalaya.sender)
|
|
|
|
"Specifying 'accounts.email.accounts.*.himalaya.sender' is deprecated, set 'accounts.email.accounts.*.himalaya.settings.sender' instead.");
|
2021-06-26 22:29:42 +00:00
|
|
|
};
|
|
|
|
}
|