{ 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; }; }