From 89a20487b2efe7c5fd62c5fc87ccf0797e96e4c3 Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Mon, 6 Aug 2018 19:04:56 +0900 Subject: [PATCH] offlineimap: init module ... is a Mail Retreival Agent (MRA) like mbsync but in python. --- modules/modules.nix | 1 + modules/programs/offlineimap.nix | 175 +++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 modules/programs/offlineimap.nix diff --git a/modules/modules.nix b/modules/modules.nix index 9b02d784..a13719ce 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -48,6 +48,7 @@ let ./programs/neovim.nix ./programs/newsboat.nix ./programs/notmuch.nix + ./programs/offlineimap.nix ./programs/pidgin.nix ./programs/rofi.nix ./programs/ssh.nix diff --git a/modules/programs/offlineimap.nix b/modules/programs/offlineimap.nix new file mode 100644 index 00000000..235f35ef --- /dev/null +++ b/modules/programs/offlineimap.nix @@ -0,0 +1,175 @@ +{ config, lib, pkgs, ... }: + +with lib; +with import ../lib/dag.nix { inherit lib; }; + +let + cfg = config.programs.offlineimap; + + accounts = + filter (a: a.notmuch.enable) + (attrValues config.accounts.email.accounts); + + # generates a script to fetch only a specific account + genOfflineImapScript = {name, ...} @ account: + pkgs.writeShellScriptBin "offlineimap-${name}" '' + ${pkgs.offlineimap}/bin/offlineimap -a${account.name} $@ + ''; + + localTypeStr = account: + if account.flavor == "gmail" then "GmailMaildir" else "Maildir"; + + remoteTypeStr = account: + if account.flavor == "gmail" then "Gmail" else "IMAP"; + + remoteHostStr = account: + if account.imap.host != null then "remotehost = "+ account.imap.host else ""; + + loginCommandStr = account: + "remoteuser = ${account.userName}"; + + passwordCommandStr = account: + let + arglist = concatMapStringsSep "," (x: "'" + toString x + "'") account.passwordCommand; + in + if account.passwordCommand != null then + ''remotepasseval = get_pass("${account.name}", [${arglist}])'' + else ""; + + postSyncHookStr = account: + if (builtins.stringLength account.offlineimap.postSyncHookCommand > 0) then + "postsynchook = ${account.offlineimap.postSyncHookCommand}" + else if account.notmuch.enable then + "postsynchook = notmuch new" + else ""; + + sslStr = account: + if account.imap.tls.enable then '' + ssl = yes + sslcacertfile = ${account.imap.tls.certificatesFile} + '' + else "ssl = no"; + + accountStr = account: with account; +'' +[Account ${name}] +localrepository = ${name}-local +remoterepository = ${name}-remote +${postSyncHookStr account} + +[Repository ${name}-local] +type = ${localTypeStr account} +localfolders = ${account.maildir.absPath} + +[Repository ${name}-remote] +type = ${remoteTypeStr account } +${remoteHostStr account} +${loginCommandStr account} +${if (account.imap.port or null) != null then "remoteport=${account.imap.port}" else ""} +${passwordCommandStr account} +realdelete = yes +maxconnections = 3 +${sslStr account} + +${account.offlineimap.extraConfig} +''; + + configFile = mailAccounts: '' +# Generated by home-manager +# see https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf +# for an exhaustive list of options +[general] +accounts = gmail +maxsyncaccounts= 4 +socktimeout = 10 +pythonfile = $XDG_CONFIG_HOME/offlineimap/get_settings.py +metadata = $XDG_DATA_HOME/offlineimap +ui = ttyui + +# user extraConfig if any +${cfg.extraConfig} + +[mbnames] +enabled = yes +filename = $XDG_CONFIG_HOME/mutt/mailboxes +header = "mailboxes *\nmailboxes !\n" +peritem = mailboxes =%(accountname)s/%(foldername)s +sep = "\n" +footer = "\n" + +${concatStringsSep "\n" (map accountStr mailAccounts)} +''; + +in +{ + + options = { + programs.offlineimap = { + enable = mkEnableOption "Offlineimap"; + + pythonFile = mkOption { + type = types.lines; + default = '' +# generated by home-manager +import subprocess + +def get_pass(service, cmd): + res = subprocess.check_output(cmd, ) + return res +''; + description = '' + Python code that can then be used in other parts of the configuration. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = '' + # in daysA + maxage=30 + ''; + description = '' + Extra configuration lines added to configuration. + You can add a [DEFAULT] section to provide defaults for all accounts. + ''; + }; + }; + + accounts.email.accounts = mkOption { + options = [ + { + offlineimap = { + enable = mkEnableOption "OfflineIMAP"; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration lines added on a per-account basis. + ''; + }; + + postSyncHookCommand = mkOption { + type = types.lines; + default = ""; + description = "command to run after fetching new mails"; + }; + }; + } + ]; + }; + }; + + config = mkIf cfg.enable { + + home.packages = [ + pkgs.offlineimap + ] ++ ( + map genOfflineImapScript ( accounts ) + ); + + xdg.configFile."offlineimap/get_settings.py".text = cfg.pythonFile; + + xdg.configFile."offlineimap/config".text = configFile accounts; + }; +}