24805d3ca7
Previously, IMAP was preferred over notmuch, even if notmuch was configured, causing problems with setting account flavor (which automatically sets IMAP settings). The new backend order is: notmuch > IMAP > maildir This also fixes the notmuch DB path being set to the wrong location. The notmuch DB is located at the maildir base path, not in each account's maildir.
272 lines
9.2 KiB
Nix
272 lines
9.2 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
# aliases
|
|
inherit (config.programs) himalaya;
|
|
tomlFormat = pkgs.formats.toml { };
|
|
|
|
# attrs util that removes entries containing a null value
|
|
compactAttrs = lib.filterAttrs (_: val: !isNull val);
|
|
|
|
# Needed for notmuch config, because the DB is here, and not in each account's dir
|
|
maildirBasePath = config.accounts.email.maildirBasePath;
|
|
|
|
# make a himalaya config from a home-manager email account config
|
|
mkAccountConfig = _: account:
|
|
let
|
|
# 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;
|
|
|
|
globalConfig = {
|
|
email = account.address;
|
|
display-name = account.realName;
|
|
default = account.primary;
|
|
folder-aliases = {
|
|
inbox = account.folders.inbox;
|
|
sent = account.folders.sent;
|
|
drafts = account.folders.drafts;
|
|
trash = account.folders.trash;
|
|
};
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
imapConfig = lib.optionalAttrs imapEnabled (compactAttrs {
|
|
backend = "imap";
|
|
imap-host = account.imap.host;
|
|
imap-port = account.imap.port;
|
|
imap-ssl = account.imap.tls.enable;
|
|
imap-starttls = account.imap.tls.useStartTls;
|
|
imap-login = account.userName;
|
|
imap-auth = "passwd";
|
|
imap-passwd.cmd = builtins.concatStringsSep " " account.passwordCommand;
|
|
});
|
|
|
|
maildirConfig = lib.optionalAttrs maildirEnabled (compactAttrs {
|
|
backend = "maildir";
|
|
maildir-root-dir = account.maildir.absPath;
|
|
});
|
|
|
|
notmuchConfig = lib.optionalAttrs notmuchEnabled (compactAttrs {
|
|
backend = "notmuch";
|
|
notmuch-db-path = maildirBasePath;
|
|
});
|
|
|
|
smtpConfig = lib.optionalAttrs (!isNull account.smtp) (compactAttrs {
|
|
sender = "smtp";
|
|
smtp-host = account.smtp.host;
|
|
smtp-port = account.smtp.port;
|
|
smtp-ssl = account.smtp.tls.enable;
|
|
smtp-starttls = account.smtp.tls.useStartTls;
|
|
smtp-login = account.userName;
|
|
smtp-auth = "passwd";
|
|
smtp-passwd.cmd = builtins.concatStringsSep " " account.passwordCommand;
|
|
});
|
|
|
|
sendmailConfig =
|
|
lib.optionalAttrs (isNull account.smtp && !isNull account.msmtp) {
|
|
sender = "sendmail";
|
|
sendmail-cmd = "${pkgs.msmtp}/bin/msmtp";
|
|
};
|
|
|
|
config = globalConfig // signatureConfig // imapConfig // maildirConfig
|
|
// notmuchConfig // smtpConfig // sendmailConfig;
|
|
|
|
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;
|
|
};
|
|
};
|
|
};
|
|
|
|
in {
|
|
meta.maintainers = with lib.hm.maintainers; [ soywod toastal ];
|
|
|
|
options = {
|
|
programs.himalaya = {
|
|
enable = lib.mkEnableOption "Enable the Himalaya email client.";
|
|
package = lib.mkPackageOption pkgs "himalaya" { };
|
|
settings = lib.mkOption {
|
|
type = lib.types.submodule { freeformType = tomlFormat.type; };
|
|
default = { };
|
|
description = ''
|
|
Himalaya global configuration.
|
|
See <link xlink:href="https://pimalaya.org/himalaya/cli/configuration/global.html"/> for supported values.
|
|
'';
|
|
};
|
|
};
|
|
|
|
services = {
|
|
himalaya-notify = {
|
|
enable =
|
|
lib.mkEnableOption "Enable the Himalaya new emails notifier service.";
|
|
|
|
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 = {
|
|
enable = lib.mkEnableOption
|
|
"Enable the Himalaya folder changes watcher service.";
|
|
|
|
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 = {
|
|
enable = lib.mkEnableOption "Enable Himalaya for this email account.";
|
|
|
|
# TODO: remove me for the next release
|
|
backend = lib.mkOption {
|
|
type = with lib.types; nullOr str;
|
|
default = null;
|
|
description = ''
|
|
Specifying 'accounts.email.accounts.*.himalaya.backend' is deprecated,
|
|
set 'accounts.email.accounts.*.himalaya.settings.backend' instead.
|
|
'';
|
|
};
|
|
|
|
# TODO: remove me for the next release
|
|
sender = lib.mkOption {
|
|
type = with lib.types; nullOr str;
|
|
description = ''
|
|
Specifying 'accounts.email.accounts.*.himalaya.sender' is deprecated,
|
|
set 'accounts.email.accounts.*.himalaya.settings.sender' instead.
|
|
'';
|
|
};
|
|
|
|
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.
|
|
'';
|
|
};
|
|
};
|
|
});
|
|
};
|
|
};
|
|
|
|
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";
|
|
|
|
# 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.");
|
|
};
|
|
}
|