khal: fix contact integration (#4836)
* khal: fix contact integration - Add tests for contact+khal - Make options `color`/`priority` available for contact accounts * khal: add separate calendar for each contact collection A contact account may have multiple VCARD collections, but Khal doesn't search recursively. Collection folder names must be hardcoded, and each has its own calendar. - Add khal.collections option for contact accounts - Default to previous setup for accounts with a single collection - Add tests * khal: specify how priority is defined by Khal See https://khal.readthedocs.io/en/latest/configure.html
This commit is contained in:
parent
4de84265d7
commit
d579633ff9
|
@ -126,6 +126,7 @@ in {
|
||||||
contactOpts
|
contactOpts
|
||||||
(import ../programs/vdirsyncer-accounts.nix)
|
(import ../programs/vdirsyncer-accounts.nix)
|
||||||
(import ../programs/khal-accounts.nix)
|
(import ../programs/khal-accounts.nix)
|
||||||
|
(import ../programs/khal-contact-accounts.nix)
|
||||||
]);
|
]);
|
||||||
default = { };
|
default = { };
|
||||||
description = "List of contacts.";
|
description = "List of contacts.";
|
||||||
|
|
|
@ -13,5 +13,39 @@ with lib;
|
||||||
Keep khal from making any changes to this account.
|
Keep khal from making any changes to this account.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
color = mkOption {
|
||||||
|
type = types.nullOr (types.enum [
|
||||||
|
"black"
|
||||||
|
"white"
|
||||||
|
"brown"
|
||||||
|
"yellow"
|
||||||
|
"dark gray"
|
||||||
|
"dark green"
|
||||||
|
"dark blue"
|
||||||
|
"light gray"
|
||||||
|
"light green"
|
||||||
|
"light blue"
|
||||||
|
"dark magenta"
|
||||||
|
"dark cyan"
|
||||||
|
"dark red"
|
||||||
|
"light magenta"
|
||||||
|
"light cyan"
|
||||||
|
"light red"
|
||||||
|
]);
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Color in which events in this calendar are displayed.
|
||||||
|
'';
|
||||||
|
example = "light green";
|
||||||
|
};
|
||||||
|
|
||||||
|
priority = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 10;
|
||||||
|
description = ''
|
||||||
|
Priority of a calendar used for coloring (calendar with highest priority is preferred).
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,39 +20,5 @@ with lib;
|
||||||
type is set to discover.
|
type is set to discover.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
color = mkOption {
|
|
||||||
type = types.nullOr (types.enum [
|
|
||||||
"black"
|
|
||||||
"white"
|
|
||||||
"brown"
|
|
||||||
"yellow"
|
|
||||||
"dark gray"
|
|
||||||
"dark green"
|
|
||||||
"dark blue"
|
|
||||||
"light gray"
|
|
||||||
"light green"
|
|
||||||
"light blue"
|
|
||||||
"dark magenta"
|
|
||||||
"dark cyan"
|
|
||||||
"dark red"
|
|
||||||
"light magenta"
|
|
||||||
"light cyan"
|
|
||||||
"light red"
|
|
||||||
]);
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Color in which events in this calendar are displayed.
|
|
||||||
'';
|
|
||||||
example = "light green";
|
|
||||||
};
|
|
||||||
|
|
||||||
priority = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 10;
|
|
||||||
description = ''
|
|
||||||
Priority of a calendar used for coloring.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
15
modules/programs/khal-contact-accounts.nix
Normal file
15
modules/programs/khal-contact-accounts.nix
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
options.khal = {
|
||||||
|
collections = mkOption {
|
||||||
|
type = types.nullOr (types.listOf types.str);
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
VCARD collections to be searched for contact birthdays.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -12,13 +12,25 @@ let
|
||||||
khalCalendarAccounts =
|
khalCalendarAccounts =
|
||||||
filterAttrs (_: a: a.khal.enable) config.accounts.calendar.accounts;
|
filterAttrs (_: a: a.khal.enable) config.accounts.calendar.accounts;
|
||||||
|
|
||||||
khalContactAccounts = mapAttrs (_: v: v // { type = "birthdays"; })
|
# a contact account may have multiple collections, each a separate calendar
|
||||||
(filterAttrs (_: a: a.khal.enable) config.accounts.contact.accounts);
|
expandContactAccount = name: acct:
|
||||||
|
if acct.khal.collections != null then
|
||||||
|
listToAttrs (map (c: {
|
||||||
|
name = "${name}-${c}";
|
||||||
|
value = recursiveUpdate acct { khal.thisCollection = c; };
|
||||||
|
}) acct.khal.collections)
|
||||||
|
else {
|
||||||
|
${name} = acct;
|
||||||
|
};
|
||||||
|
|
||||||
|
khalContactAccounts = concatMapAttrs expandContactAccount
|
||||||
|
(mapAttrs (_: v: recursiveUpdate v { khal.type = "birthdays"; })
|
||||||
|
(filterAttrs (_: a: a.khal.enable) config.accounts.contact.accounts));
|
||||||
|
|
||||||
khalAccounts = khalCalendarAccounts // khalContactAccounts;
|
khalAccounts = khalCalendarAccounts // khalContactAccounts;
|
||||||
|
|
||||||
primaryAccount = findSingle (a: a.primary) null null
|
primaryAccount = findSingle (a: a.primary) null null
|
||||||
(mapAttrsToList (n: v: v // { name = n; }) khalAccounts);
|
(mapAttrsToList (n: v: v // { name = n; }) khalCalendarAccounts);
|
||||||
|
|
||||||
definedAttrs = filterAttrs (_: v: !isNull v);
|
definedAttrs = filterAttrs (_: v: !isNull v);
|
||||||
|
|
||||||
|
@ -30,6 +42,9 @@ let
|
||||||
"path = ${
|
"path = ${
|
||||||
value.local.path + "/"
|
value.local.path + "/"
|
||||||
+ (optionalString (value.khal.type == "discover") value.khal.glob)
|
+ (optionalString (value.khal.type == "discover") value.khal.glob)
|
||||||
|
+ (optionalString
|
||||||
|
(value.khal.type == "birthdays" && value.khal ? thisCollection)
|
||||||
|
value.khal.thisCollection)
|
||||||
}"
|
}"
|
||||||
] ++ optional (value.khal.readOnly) "readonly = True" ++ [
|
] ++ optional (value.khal.readOnly) "readonly = True" ++ [
|
||||||
(toKeyValueIfDefined (getAttrs [ "type" "color" "priority" ] value.khal))
|
(toKeyValueIfDefined (getAttrs [ "type" "color" "priority" ] value.khal))
|
||||||
|
@ -153,7 +168,7 @@ in {
|
||||||
locale = mkOption {
|
locale = mkOption {
|
||||||
type = lib.types.submodule { options = localeOptions; };
|
type = lib.types.submodule { options = localeOptions; };
|
||||||
description = ''
|
description = ''
|
||||||
khal locale settings.
|
khal locale settings.
|
||||||
'';
|
'';
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,36 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
accounts.contact = {
|
||||||
|
basePath = "$XDG_CONFIG_HOME/card";
|
||||||
|
accounts = {
|
||||||
|
testcontacts = {
|
||||||
|
khal = {
|
||||||
|
enable = true;
|
||||||
|
collections = [ "default" "automaticallyCollected" ];
|
||||||
|
};
|
||||||
|
local.type = "filesystem";
|
||||||
|
local.fileExt = ".vcf";
|
||||||
|
name = "testcontacts";
|
||||||
|
remote = {
|
||||||
|
type = "http";
|
||||||
|
url = "https://example.com/contacts.vcf";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testcontactsNoCollections = {
|
||||||
|
khal.enable = true;
|
||||||
|
local.type = "filesystem";
|
||||||
|
local.fileExt = ".vcf";
|
||||||
|
name = "testcontactsNoCollections";
|
||||||
|
remote = {
|
||||||
|
type = "http";
|
||||||
|
url = "https://example.com/contacts.vcf";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
test.stubs = { khal = { }; };
|
test.stubs = { khal = { }; };
|
||||||
|
|
||||||
nmt.script = ''
|
nmt.script = ''
|
||||||
|
|
|
@ -7,6 +7,27 @@ type=calendar
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[testcontacts-automaticallyCollected]]
|
||||||
|
path = /home/hm-user/$XDG_CONFIG_HOME/card/testcontacts/automaticallyCollected
|
||||||
|
priority=10
|
||||||
|
type=birthdays
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[testcontacts-default]]
|
||||||
|
path = /home/hm-user/$XDG_CONFIG_HOME/card/testcontacts/default
|
||||||
|
priority=10
|
||||||
|
type=birthdays
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[testcontactsNoCollections]]
|
||||||
|
path = /home/hm-user/$XDG_CONFIG_HOME/card/testcontactsNoCollections/
|
||||||
|
priority=10
|
||||||
|
type=birthdays
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[default]
|
[default]
|
||||||
default_calendar=test
|
default_calendar=test
|
||||||
highlight_event_days=true
|
highlight_event_days=true
|
||||||
|
|
Loading…
Reference in a new issue