diff options
Diffstat (limited to 'infra/libkookie/home-manager/modules/programs/offlineimap.nix')
-rw-r--r-- | infra/libkookie/home-manager/modules/programs/offlineimap.nix | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/infra/libkookie/home-manager/modules/programs/offlineimap.nix b/infra/libkookie/home-manager/modules/programs/offlineimap.nix new file mode 100644 index 000000000000..b6ba847e9b79 --- /dev/null +++ b/infra/libkookie/home-manager/modules/programs/offlineimap.nix @@ -0,0 +1,178 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.offlineimap; + + accounts = filter (a: a.offlineimap.enable) + (attrValues config.accounts.email.accounts); + + toIni = generators.toINI { + mkKeyValue = key: value: + let + value' = if isBool value then + (if value then "yes" else "no") + else + toString value; + in "${key} = ${value'}"; + }; + + # Generates a script to fetch only a specific account. + # + # Note, these scripts are not actually created and installed at the + # moment. It will need some thinking on whether this is a good idea + # and whether other modules should have some similar functionality. + # + # Perhaps have a single tool `email` that wraps the command? + # Something like + # + # $ email <account name> <program name> <program args> + genOfflineImapScript = account: + with account; + pkgs.writeShellScriptBin "offlineimap-${name}" '' + exec ${pkgs.offlineimap}/bin/offlineimap -a${account.name} "$@" + ''; + + accountStr = account: + with account; + let + postSyncHook = optionalAttrs (offlineimap.postSyncHookCommand != "") { + postsynchook = pkgs.writeShellScriptBin "postsynchook" + offlineimap.postSyncHookCommand + "/bin/postsynchook"; + }; + + localType = + if account.flavor == "gmail.com" then "GmailMaildir" else "Maildir"; + + remoteType = if account.flavor == "gmail.com" then "Gmail" else "IMAP"; + + remoteHost = + optionalAttrs (imap.host != null) { remotehost = imap.host; }; + + remotePort = + optionalAttrs ((imap.port or null) != null) { remoteport = imap.port; }; + + ssl = if imap.tls.enable then { + ssl = true; + sslcacertfile = imap.tls.certificatesFile; + starttls = imap.tls.useStartTls; + } else { + ssl = false; + }; + + remotePassEval = + let arglist = concatMapStringsSep "," (x: "'${x}'") passwordCommand; + in optionalAttrs (passwordCommand != null) { + remotepasseval = ''get_pass("${name}", [${arglist}])''; + }; + in toIni { + "Account ${name}" = { + localrepository = "${name}-local"; + remoterepository = "${name}-remote"; + } // postSyncHook // offlineimap.extraConfig.account; + + "Repository ${name}-local" = { + type = localType; + localfolders = maildir.absPath; + } // offlineimap.extraConfig.local; + + "Repository ${name}-remote" = { + type = remoteType; + remoteuser = userName; + } // remoteHost // remotePort // remotePassEval // ssl + // offlineimap.extraConfig.remote; + }; + + extraConfigType = with types; attrsOf (either (either str int) bool); + +in { + options = { + programs.offlineimap = { + enable = mkEnableOption "OfflineIMAP"; + + pythonFile = mkOption { + type = types.lines; + default = '' + import subprocess + + def get_pass(service, cmd): + return subprocess.check_output(cmd, ) + ''; + description = '' + Python code that can then be used in other parts of the + configuration. + ''; + }; + + extraConfig.general = mkOption { + type = extraConfigType; + default = { }; + example = { + maxage = 30; + ui = "blinkenlights"; + }; + description = '' + Extra configuration options added to the + <option>general</option> section. + ''; + }; + + extraConfig.default = mkOption { + type = extraConfigType; + default = { }; + example = { gmailtrashfolder = "[Gmail]/Papierkorb"; }; + description = '' + Extra configuration options added to the + <option>DEFAULT</option> section. + ''; + }; + + extraConfig.mbnames = mkOption { + type = extraConfigType; + default = { }; + example = literalExample '' + { + filename = "~/.config/mutt/mailboxes"; + header = "'mailboxes '"; + peritem = "'+%(accountname)s/%(foldername)s'"; + sep = "' '"; + footer = "'\\n'"; + } + ''; + description = '' + Extra configuration options added to the + <code>mbnames</code> section. + ''; + }; + }; + + accounts.email.accounts = mkOption { + type = with types; + attrsOf (submodule (import ./offlineimap-accounts.nix)); + }; + }; + + config = mkIf cfg.enable { + home.packages = [ pkgs.offlineimap ]; + + xdg.configFile."offlineimap/get_settings.py".text = cfg.pythonFile; + + xdg.configFile."offlineimap/config".text = '' + # Generated by Home Manager. + # See https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf + # for an exhaustive list of options. + '' + toIni ({ + general = { + accounts = concatMapStringsSep "," (a: a.name) accounts; + pythonfile = "${config.xdg.configHome}/offlineimap/get_settings.py"; + metadata = "${config.xdg.dataHome}/offlineimap"; + } // cfg.extraConfig.general; + } // optionalAttrs (cfg.extraConfig.mbnames != { }) { + mbnames = { enabled = true; } // cfg.extraConfig.mbnames; + } // optionalAttrs (cfg.extraConfig.default != { }) { + DEFAULT = cfg.extraConfig.default; + }) + "\n" + concatStringsSep "\n" (map accountStr accounts); + }; +} |