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/msmtp-accounts.nix)
|
||||
(import ../programs/notmuch-accounts.nix)
|
||||
(import ../programs/offlineimap-accounts.nix)
|
||||
]);
|
||||
default = {};
|
||||
description = "List of email accounts.";
|
||||
|
|
|
@ -772,6 +772,13 @@ in
|
|||
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/newsboat.nix
|
||||
./programs/notmuch.nix
|
||||
./programs/offlineimap.nix
|
||||
./programs/pidgin.nix
|
||||
./programs/rofi.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