offlineimap: add module
OfflineIMAP is a Mail Retrieval Agent (MRA) like mbsync but written in Python.
This commit is contained in:
parent
4602c00dcf
commit
5eca556fe7
|
@ -320,6 +320,7 @@ in
|
||||||
(import ../programs/mbsync-accounts.nix)
|
(import ../programs/mbsync-accounts.nix)
|
||||||
(import ../programs/msmtp-accounts.nix)
|
(import ../programs/msmtp-accounts.nix)
|
||||||
(import ../programs/notmuch-accounts.nix)
|
(import ../programs/notmuch-accounts.nix)
|
||||||
|
(import ../programs/offlineimap-accounts.nix)
|
||||||
]);
|
]);
|
||||||
default = {};
|
default = {};
|
||||||
description = "List of email accounts.";
|
description = "List of email accounts.";
|
||||||
|
|
|
@ -772,6 +772,13 @@ in
|
||||||
A new module is available: 'services.pasystray'.
|
A new module is available: 'services.pasystray'.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
time = "2018-08-29T20:27:04+00:00";
|
||||||
|
message = ''
|
||||||
|
A new module is available: 'programs.offlineimap'.
|
||||||
|
'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ let
|
||||||
./programs/neovim.nix
|
./programs/neovim.nix
|
||||||
./programs/newsboat.nix
|
./programs/newsboat.nix
|
||||||
./programs/notmuch.nix
|
./programs/notmuch.nix
|
||||||
|
./programs/offlineimap.nix
|
||||||
./programs/pidgin.nix
|
./programs/pidgin.nix
|
||||||
./programs/rofi.nix
|
./programs/rofi.nix
|
||||||
./programs/ssh.nix
|
./programs/ssh.nix
|
||||||
|
|
46
modules/programs/offlineimap-accounts.nix
Normal file
46
modules/programs/offlineimap-accounts.nix
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
extraConfigType = with types; attrsOf (either (either str int) bool);
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.offlineimap = {
|
||||||
|
enable = mkEnableOption "OfflineIMAP";
|
||||||
|
|
||||||
|
extraConfig.local = mkOption {
|
||||||
|
type = extraConfigType;
|
||||||
|
default = {};
|
||||||
|
example = {
|
||||||
|
sync_deletes = true;
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Extra configuration options to add to the local account
|
||||||
|
section.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig.remote = mkOption {
|
||||||
|
type = extraConfigType;
|
||||||
|
default = {};
|
||||||
|
example = {
|
||||||
|
maxconnections = 2;
|
||||||
|
expunge = false;
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Extra configuration options to add to the remote account
|
||||||
|
section.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
postSyncHookCommand = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = "Command to run after fetching new mails.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
206
modules/programs/offlineimap.nix
Normal file
206
modules/programs/offlineimap.nix
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
{ 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;
|
||||||
|
|
||||||
|
"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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue