diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 1953354d6..2dafe1fdc 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1122,6 +1122,14 @@ in 'foo.conf.bck'. ''; } + + { + time = "2019-06-19T17:49:29+00:00"; + message = '' + A new module is available: `services.getmail`. + ''; + } + ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index af0cbc1ca..6900ed67d 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -99,6 +99,7 @@ let (loadModule ./services/gnome-keyring.nix { }) (loadModule ./services/gpg-agent.nix { }) (loadModule ./services/imapnotify.nix { condition = hostPlatform.isLinux; }) + (loadModule ./services/getmail.nix { }) (loadModule ./services/kbfs.nix { }) (loadModule ./services/kdeconnect.nix { }) (loadModule ./services/keepassx.nix { }) diff --git a/modules/services/getmail.nix b/modules/services/getmail.nix new file mode 100644 index 000000000..74c9cf6b6 --- /dev/null +++ b/modules/services/getmail.nix @@ -0,0 +1,205 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.getmail; + + retrieverModule = types.submodule ({config,...}: { + options = { + type = mkOption { + type = types.enum [ + "SimplePOP3Retriever" + "SimplePOP3SSLRetriever" + "SimpleIMAPRetriever" + "SimpleIMAPSSLRetriever" + ]; + default = "SimpleIMAPSSLRetriever"; + description = "Type of the retriever."; + }; + + server = mkOption { + type = types.string; + default = ""; + description = "The remote server."; + }; + + username = mkOption { + type = types.string; + default = ""; + description = "The server username."; + }; + + password = mkOption { + type = types.nullOr types.string; + default = null; + description = '' + The server password. Note that the passwords are stored clear in the + nix store, so it is recommended to not use this field, but instead + either leave empty or use passwordCommand instead. + ''; + }; + + passwordCommand = mkOption { + type = types.nullOr (types.listOf types.string); + default = null; + example = ["${pkgs.gnupg}/bin/gpg" "--decrypt" "file.gpg"]; + description = '' + The server password. With this the password is retrieved with the + given command. The list value is given escaped to the implementation. + ''; + }; + + mailboxes = mkOption { + type = types.listOf types.string; + default = []; + description = "A list of mailboxes"; + }; + }; + }); + + destinationModule = types.submodule ({config,...}: { + options = { + type = mkOption { + type = types.enum [ + "MDA_external" + "Maildir" + ]; + default = "Maildir"; + description = "Destination type."; + }; + + path = mkOption { + type = types.string; + default = "$HOME/Mail"; + example = "${pkgs.procmail}/bin/procmail"; + description = '' + The destination path. For Maildir it's the file + path and for MDA_external it's the destination + application. + ''; + }; + }; + }); + + optionsModule = types.submodule ({config,...}: { + options = { + delete = mkOption { + type = types.bool; + default = false; + description = '' + Enable if you want to delete read messages from the server. Most + users should either enable delete or disable + readAll. + ''; + }; + + readAll = mkOption { + type = types.bool; + default = true; + description = '' + Enable if you want to fetch all, even the read messages from the + server. Most users should either enable delete or + disable readAll. + ''; + }; + }; + }); + +in + +{ + options = { + programs.getmail = { + enable = mkEnableOption "Enable getmail"; + + retriever = mkOption { + type = retrieverModule; + default = {}; + description = "The server section."; + }; + + destination = mkOption { + type = destinationModule; + default = {}; + description = "The destination section."; + }; + + options = mkOption { + type = optionsModule; + default = {}; + description = "The options section."; + }; + + frequency = mkOption { + type = types.string; + default = "*:0/15"; + example = "hourly"; + description = '' + The refresh frequency. Check man systemd.time for + more information on the syntax. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + home.file.".getmail/getmailrc".text = + let + quoted = x: "\"${escape ["\""] x}\""; + + passwordCommand = concatStringsSep ", " (map quoted cfg.retriever.passwordCommand); + + password = if cfg.retriever.passwordCommand != null + then "password_command = (${passwordCommand})" + else optionalString (cfg.retriever.password != null) "password = \"${quoted cfg.retriever.password}\""; + mailboxInner = concatStringsSep ", " ( + map quoted cfg.retriever.mailboxes); + + mailboxes = "(${mailboxInner})"; + + in + + '' + [retriever] + type = ${cfg.retriever.type} + server = ${cfg.retriever.server} + username = ${cfg.retriever.username} + ${password} + mailboxes = ${mailboxes} + + [destination] + type = ${cfg.destination.type} + path = ${cfg.destination.path} + + [options] + delete = ${toString cfg.options.delete} + read_all = ${toString cfg.options.readAll} + ''; + + systemd.user.services.getmail = { + Unit = { + Description = "getmail email fetcher"; + PartOf = ["network-online.target"]; + }; + Service = { + Type = "simple"; + ExecStart = "${pkgs.getmail}/bin/getmail"; + }; + }; + + systemd.user.timers.getmail = { + Unit = { + Description = "getmail email fetcher"; + }; + Timer = { + OnCalendar = "${cfg.frequency}"; + Unit = "getmail.service"; + }; + Install = { + WantedBy = [ "timers.target" ]; + }; + }; + }; +}