diff --git a/modules/misc/news.nix b/modules/misc/news.nix index c27ba8b4d..dfa9b81fa 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1193,6 +1193,13 @@ in A new module is available: 'programs.pqiv'. ''; } + + { + time = "2023-08-22T16:06:52+00:00"; + message = '' + A new module is available: 'programs.qcal'. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index d4fc5afdc..4c82d2041 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -173,6 +173,7 @@ let ./programs/pubs.nix ./programs/pyenv.nix ./programs/pylint.nix + ./programs/qcal.nix ./programs/qutebrowser.nix ./programs/rbw.nix ./programs/readline.nix diff --git a/modules/programs/qcal.nix b/modules/programs/qcal.nix new file mode 100644 index 000000000..c70a6ea38 --- /dev/null +++ b/modules/programs/qcal.nix @@ -0,0 +1,66 @@ +{ config, lib, pkgs, ... }: + +let + + cfg = config.programs.qcal; + + qcalAccounts = lib.attrValues + (lib.filterAttrs (_: a: a.qcal.enable) config.accounts.calendar.accounts); + + rename = oldname: + builtins.getAttr oldname { + url = "Url"; + userName = "Username"; + passwordCommand = "PasswordCmd"; + }; + + filteredAccounts = let + mkAccount = account: + lib.filterAttrs (_: v: v != null) (with account.remote; { + Url = url; + Username = if userName == null then null else userName; + PasswordCmd = + if passwordCommand == null then null else toString passwordCommand; + }); + in map mkAccount qcalAccounts; + +in { + meta.maintainers = with lib.maintainers; [ antonmosich ]; + + options = { + programs.qcal = { + enable = lib.mkEnableOption "qcal, a CLI calendar application"; + + timezone = lib.mkOption { + type = lib.types.singleLineStr; + default = "Local"; + example = "Europe/Vienna"; + description = "Timezone to display calendar entries in"; + }; + + defaultNumDays = lib.mkOption { + type = lib.types.ints.positive; + default = 30; + description = "Default number of days to show calendar entries for"; + }; + }; + + accounts.calendar.accounts = lib.mkOption { + type = with lib.types; + attrsOf + (submodule { options.qcal.enable = lib.mkEnableOption "qcal access"; }); + }; + }; + + config = lib.mkIf cfg.enable { + home.packages = [ pkgs.qcal ]; + + xdg.configFile."qcal/config.json".source = + let jsonFormat = pkgs.formats.json { }; + in jsonFormat.generate "qcal.json" { + DefaultNumDays = cfg.defaultNumDays; + Timezone = cfg.timezone; + Calendars = filteredAccounts; + }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 615146e02..b407f5fb4 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -120,6 +120,7 @@ import nmt { ./modules/programs/powerline-go ./modules/programs/pubs ./modules/programs/pyenv + ./modules/programs/qcal ./modules/programs/qutebrowser ./modules/programs/readline ./modules/programs/ripgrep diff --git a/tests/modules/programs/qcal/default.nix b/tests/modules/programs/qcal/default.nix new file mode 100644 index 000000000..3a177e364 --- /dev/null +++ b/tests/modules/programs/qcal/default.nix @@ -0,0 +1,5 @@ +{ + qcal-http = ./http-calendar.nix; + qcal-webdav = ./webdav-calendar.nix; + qcal-mixed = ./mixed.nix; +} diff --git a/tests/modules/programs/qcal/http-calendar.json-expected b/tests/modules/programs/qcal/http-calendar.json-expected new file mode 100644 index 000000000..7b39cdf9a --- /dev/null +++ b/tests/modules/programs/qcal/http-calendar.json-expected @@ -0,0 +1,9 @@ +{ + "Calendars": [ + { + "Url": "https://example.com/events.ical" + } + ], + "DefaultNumDays": 30, + "Timezone": "Local" +} diff --git a/tests/modules/programs/qcal/http-calendar.nix b/tests/modules/programs/qcal/http-calendar.nix new file mode 100644 index 000000000..c32440601 --- /dev/null +++ b/tests/modules/programs/qcal/http-calendar.nix @@ -0,0 +1,18 @@ +{ pkgs, lib, ... }: + +{ + programs.qcal.enable = true; + accounts.calendar.accounts.test = { + qcal.enable = true; + remote = { url = "https://example.com/events.ical"; }; + }; + + test.stubs = { qcal = { }; }; + + nmt.script = '' + assertFileExists home-files/.config/qcal/config.json + assertFileContent home-files/.config/qcal/config.json ${ + ./http-calendar.json-expected + } + ''; +} diff --git a/tests/modules/programs/qcal/mixed.json-expected b/tests/modules/programs/qcal/mixed.json-expected new file mode 100644 index 000000000..6546efda3 --- /dev/null +++ b/tests/modules/programs/qcal/mixed.json-expected @@ -0,0 +1,14 @@ +{ + "Calendars": [ + { + "Url": "https://example.com/events.ical" + }, + { + "PasswordCmd": "pass show calendar", + "Url": "https://cal.example.com/anton/work", + "Username": "anton" + } + ], + "DefaultNumDays": 30, + "Timezone": "Local" +} diff --git a/tests/modules/programs/qcal/mixed.nix b/tests/modules/programs/qcal/mixed.nix new file mode 100644 index 000000000..d2241bdcb --- /dev/null +++ b/tests/modules/programs/qcal/mixed.nix @@ -0,0 +1,28 @@ +{ pkgs, lib, ... }: + +{ + programs.qcal.enable = true; + accounts.calendar.accounts = { + http-test = { + remote = { url = "https://example.com/events.ical"; }; + qcal.enable = true; + }; + webdav-test = { + remote = { + url = "https://cal.example.com/anton/work"; + userName = "anton"; + passwordCommand = [ "pass" "show" "calendar" ]; + }; + qcal.enable = true; + }; + }; + + test.stubs = { qcal = { }; }; + + nmt.script = '' + assertFileExists home-files/.config/qcal/config.json + assertFileContent home-files/.config/qcal/config.json ${ + ./mixed.json-expected + } + ''; +} diff --git a/tests/modules/programs/qcal/webdav-calendar.json-expected b/tests/modules/programs/qcal/webdav-calendar.json-expected new file mode 100644 index 000000000..c7426cb33 --- /dev/null +++ b/tests/modules/programs/qcal/webdav-calendar.json-expected @@ -0,0 +1,11 @@ +{ + "Calendars": [ + { + "PasswordCmd": "pass show calendar", + "Url": "https://cal.example.com/anton/work", + "Username": "anton" + } + ], + "DefaultNumDays": 23, + "Timezone": "Europe/Berlin" +} diff --git a/tests/modules/programs/qcal/webdav-calendar.nix b/tests/modules/programs/qcal/webdav-calendar.nix new file mode 100644 index 000000000..caefe1f16 --- /dev/null +++ b/tests/modules/programs/qcal/webdav-calendar.nix @@ -0,0 +1,26 @@ +{ pkgs, lib, ... }: + +{ + programs.qcal = { + enable = true; + defaultNumDays = 23; + timezone = "Europe/Berlin"; + }; + accounts.calendar.accounts.test = { + qcal.enable = true; + remote = { + url = "https://cal.example.com/anton/work"; + userName = "anton"; + passwordCommand = [ "pass" "show" "calendar" ]; + }; + }; + + test.stubs = { qcal = { }; }; + + nmt.script = '' + assertFileExists home-files/.config/qcal/config.json + assertFileContent home-files/.config/qcal/config.json ${ + ./webdav-calendar.json-expected + } + ''; +}