diff --git a/modules/home-manager/services/recoll.nix b/modules/home-manager/services/recoll.nix new file mode 100644 index 00000000..985c814d --- /dev/null +++ b/modules/home-manager/services/recoll.nix @@ -0,0 +1,146 @@ +{ config, options, lib, pkgs, ... }: + +let + cfg = config.services.recoll; + + # The key-value generator for Recoll config format. For future references, + # see the example configuration from the package (i.e., + # `$out/share/recoll/examples/recoll.conf`). + mkRecollConfKeyValue = lib.generators.mkKeyValueDefault { + mkValueString = v: + if v == true then + "1" + else if v == false then + "0" + else + lib.generators.mkValueStringDefault { } v; + } " = "; + + # A modified version of 'lib.generators.toINI' that also accepts top-level + # attributes as non-attrsets. + toRecollConf = with lib; + { listsAsDuplicateKeys ? false }: + attr: + let + toKeyValue = generators.toKeyValue { + inherit listsAsDuplicateKeys; + mkKeyValue = mkRecollConfKeyValue; + }; + mkSectionName = name: strings.escape [ "[" "]" ] name; + config = mapAttrsToList (k: v: + if isAttrs v then + '' + [${mkSectionName k}] + '' + toKeyValue v + else + toKeyValue { "${k}" = v; }) attr; + in concatStringsSep "\n" config; + + # A specific type for Recoll config format. Taken from `pkgs.formats` + # implementation from nixpkgs. See the 'Nix-representable formats' from the + # NixOS manual for more information. + recollConfFormat = { }: { + type = with lib.types; + let + valueType = + nullOr (oneOf [ bool float int path str (attrsOf valueType) ]) // { + description = "Recoll config value"; + }; + in attrsOf valueType; + + generate = name: value: pkgs.writeText name (toRecollConf { } value); + }; + + # The actual object we're going to use for this module. This is for the sake + # of consistency (and dogfooding the settings format implementation). + settingsFormat = recollConfFormat { }; +in { + options.services.recoll = { + enable = lib.mkEnableOption "Recoll file index service"; + + startAt = lib.mkOption { + type = lib.types.str; + default = "hourly"; + example = "00/2:00"; + description = '' + When or how often the periodic update should run. Must be the format + described from systemd.time(7). + ''; + }; + + settings = lib.mkOption { + type = settingsFormat.type; + default = { }; + description = '' + The configuration to be written at + ''${config.services.recoll.configDir}/recoll.conf. + + See recoll.conf(5) manual page for more details. + ''; + example = lib.literalExpression '' + { + topdirs = "~/Downloads ~/Documents ~/projects"; + + "~/Downloads" = { + "skippedNames+" = "*.iso"; + }; + + "~/projects" = { + "skippedNames+" = "node_modules target result"; + }; + } + ''; + }; + + configDir = lib.mkOption { + type = lib.types.str; + default = "${config.home.homeDirectory}/.recoll"; + example = "\${xdg.configHome.\"recoll\"}"; + description = "The directory to contain Recoll configuration files."; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.recoll" pkgs + lib.platforms.linux) + ]; + + home.packages = [ pkgs.recoll ]; + + home.sessionVariables = { RECOLL_CONFDIR = cfg.configDir; }; + + home.file."${cfg.configDir}/recoll.conf".source = + settingsFormat.generate "recoll-${config.home.username}" cfg.settings; + + systemd.user.services.recollindex = { + Unit = { + Description = "Recoll index update"; + Documentation = [ + "man:recoll" + "man:recollindex" + "https://www.lesbonscomptes.com/recoll/usermanual/" + ]; + }; + + Service = { + ExecStart = "${pkgs.recoll}/bin/recollindex"; + Environment = [ "RECOLL_CONFDIR=${cfg.configDir}" ]; + }; + }; + + systemd.user.timers.recollindex = { + Unit = { + Description = "Recoll index update"; + PartOf = [ "default.target" ]; + }; + + Timer = { + Persistent = true; + OnCalendar = cfg.startAt; + }; + + Install.WantedBy = [ "timers.target" ]; + }; + }; +} diff --git a/users/home-manager/foo-dogsquared/default.nix b/users/home-manager/foo-dogsquared/default.nix index b0f1a093..06e3a971 100644 --- a/users/home-manager/foo-dogsquared/default.nix +++ b/users/home-manager/foo-dogsquared/default.nix @@ -28,6 +28,21 @@ mopidy-mpris mopidy-local ]; + + services.recoll = { + enable = true; + settings = { + topdirs = "~/Downloads ~/Documents ~/library"; + "skippedNames+" = "node_modules"; + + "~/library/projects" = { + "skippedNames+" = ".editorconfig .gitignore result flake.lock go.sum"; + }; + + "~/library/projects/software" = { + "skippedNames+" = "target result"; + }; + }; }; # My custom modules.