mirror of
https://github.com/nix-community/home-manager
synced 2024-08-20 11:06:30 +02:00
Nixpkgs switched to OfflineIMAP version 8 which means that Python 3 is now used instead of Python 2. As a result, get_pass() now returns a byte array instead of a string and the argument to get_pass() must be a byte array too. See https://github.com/OfflineIMAP/offlineimap3/issues/103.
190 lines
5.7 KiB
Nix
190 lines
5.7 KiB
Nix
{ 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 = toString 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}]).strip(b"\n")'';
|
|
};
|
|
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 = literalExpression ''
|
|
{
|
|
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/get_settings.pyc".source = "${
|
|
pkgs.runCommandLocal "get_settings-compile" {
|
|
nativeBuildInputs = [ pkgs.python2 ];
|
|
pythonFile = cfg.pythonFile;
|
|
passAsFile = [ "pythonFile" ];
|
|
} ''
|
|
mkdir -p $out/bin
|
|
cp $pythonFilePath $out/bin/get_settings.py
|
|
python2 -m py_compile $out/bin/get_settings.py
|
|
''
|
|
}/bin/get_settings.pyc";
|
|
|
|
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);
|
|
};
|
|
}
|