{ lib, config, pkgs, masterModulesPath, inputs, ... }: with lib; let psCfg = config.pub-solar; cfg = config.pub-solar.paperless; xdg = config.home-manager.users."${psCfg.user.name}".xdg; in { imports = [ "${masterModulesPath}/services/misc/paperless.nix" ]; disabledModules = [ "services/misc/paperless.nix" ]; options.pub-solar.paperless = { enable = mkEnableOption "All you need to go paperless"; ocrLanguage = mkOption { description = "OCR language"; type = types.str; example = "eng+deu"; default = "eng"; }; dataDir = mkOption { description = "Directory to save data in"; type = types.str; example = "/home/pub_solar/Paperless"; default = "${xdg.dataHome}/Paperless"; }; consumptionDir = mkOption { description = "Directory to be watched"; type = types.str; example = "/var/lib/paperless/consume"; default = "/var/lib/paperless/consume"; }; sync = { enable = mkEnableOption '' You can use this option to sync several paperless instances, for example via nextcloud. It will sync the media directory and database, automatically merging sqlite dbs via dump and import. Logs, the classification model, and other files are left unsynced. ''; masterNode = mkEnableOption "If this node is the master node, it will only export paperless data, otherwise it will only import"; directory = mkOption { description = "Directory to sync with."; type = types.str; example = "/home/pub_solar/Nextcloud/Paperless"; default = "/home/${psCfg.user.name}/Nextcloud/Paperless"; }; }; scannerDefaultDevice = mkOption { description = '' The scanner device. To find this, use `scanimage -L`. For example, your output might be the following: ``` device `v4l:/dev/video3' is a Noname Logitech StreamCam virtual device device `hp3900:libusb:005:002' is a Hewlett-Packard Scanjet G3010 flatbed scanner ``` Here, the scannerDevice is `hp3900:libusb:005:002`. ''; type = types.str; example = "hp3900:libusb:005:002"; default = ""; }; }; config = mkIf cfg.enable { services.paperless = { enable = true; user = psCfg.user.name; consumptionDir = cfg.consumptionDir; dataDir = cfg.dataDir; address = "paperless.local"; extraConfig = { PAPERLESS_OCR_LANGUAGE = cfg.ocrLanguage; PAPERLESS_ADMIN_USER = psCfg.user.name; PAPERLESS_AUTO_LOGIN_USERNAME = psCfg.user.name; PAPERLESS_URL = "http://paperless.local"; }; }; home-manager = pkgs.lib.setAttrByPath ["users" psCfg.user.name] { home.packages = with pkgs; [ inputs.scan2paperless.legacyPackages.x86_64-linux.scan2paperless sane-backends python310Packages.img2pdf ]; home.sessionVariables = { SCANNER_DEFAULT_DEVICE = cfg.scannerDefaultDevice; SCANNER_OUTPUT_DIR = cfg.consumptionDir; }; systemd.user.sessionVariables = { SCANNER_DEFAULT_DEVICE = cfg.scannerDefaultDevice; SCANNER_OUTPUT_DIR = cfg.consumptionDir; }; }; systemd = let copy-out = pkgs.writeShellScriptBin "copy-out" '' ${pkgs.systemd}/bin/systemctl stop paperless-web.service paperless-task-queue.service paperless-scheduler.service paperless-consumer.service cp -r ${cfg.dataDir}/media ${cfg.sync.directory}/ cp ${cfg.dataDir}/db.sqlite3 ${cfg.sync.directory}/db.sqlite3 cp ${cfg.dataDir}/celerybeat-schedule.db ${cfg.sync.directory}/celerybeat-schedule.db cp ${cfg.dataDir}/classification_model.pickle ${cfg.sync.directory}/classification_model.pickle cp ${cfg.dataDir}/src-version ${cfg.sync.directory}/src-version chown -R ${psCfg.user.name}:users ${cfg.sync.directory} ${pkgs.systemd}/bin/systemctl start paperless-web.service paperless-task-queue.service paperless-scheduler.service paperless-consumer.service ''; copy-in = pkgs.writeShellScriptBin "copy-in" '' ${pkgs.systemd}/bin/systemctl stop paperless-web.service paperless-task-queue.service paperless-scheduler.service paperless-consumer.service cp -r ${cfg.sync.directory}/media ${cfg.dataDir}/ cp ${cfg.sync.directory}/db.sqlite3 ${cfg.dataDir}/db.sqlite3 cp ${cfg.sync.directory}/celerybeat-schedule.db ${cfg.dataDir}/celerybeat-schedule.db cp ${cfg.sync.directory}/classification_model.pickle ${cfg.dataDir}/classification_model.pickle cp ${cfg.sync.directory}/src-version ${cfg.dataDir}/src-version ${pkgs.systemd}/bin/systemctl start paperless-web.service paperless-task-queue.service paperless-scheduler.service paperless-consumer.service ''; in mkIf cfg.sync.enable { services.nextcloud-paperless-autosync = { unitConfig = { Description = "Auto sync paperless to or from Nextcloud"; After = "network-online.target"; }; serviceConfig = { Type = "simple"; ExecStart= if cfg.sync.masterNode then "${copy-out}/bin/copy-out" else "${copy-in}/bin/copy-in"; TimeoutStopSec = "180"; KillMode = "process"; KillSignal = "SIGINT"; }; wantedBy = ["multi-user.target"]; }; timers.nextcloud-paperless-autosync = { unitConfig.Description = "Automatic sync files with Nextcloud when booted up after 5 minutes then rerun every 30 minutes"; timerConfig.OnUnitActiveSec = "30min"; wantedBy = ["multi-user.target" "timers.target"]; }; }; }; }