nixpkgs/nixos/modules/services/hardware/scanservjs.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

154 lines
3.9 KiB
Nix
Raw Normal View History

{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.scanservjs;
settings = {
scanimage = lib.getExe' config.hardware.sane.backends-package "scanimage";
convert = lib.getExe' pkgs.imagemagick "convert";
tesseract = lib.getExe pkgs.tesseract;
# it defaults to config/devices.json, but "config" dir doesn't exist by default and scanservjs doesn't create it
devicesPath = "devices.json";
} // cfg.settings;
settingsFormat = pkgs.formats.json { };
leafs =
attrs:
builtins.concatLists (
lib.mapAttrsToList (k: v: if builtins.isAttrs v then leafs v else [ v ]) attrs
);
package = pkgs.scanservjs;
configFile = pkgs.writeText "config.local.js" ''
/* eslint-disable no-unused-vars */
module.exports = {
afterConfig(config) {
${builtins.concatStringsSep "" (
leafs (
lib.mapAttrsRecursive (path: val: ''
${builtins.concatStringsSep "." path} = ${builtins.toJSON val};
'') { config = settings; }
)
)}
${cfg.extraConfig}
},
afterDevices(devices) {
${cfg.extraDevicesConfig}
},
async afterScan(fileInfo) {
${cfg.runAfterScan}
},
actions: [
${builtins.concatStringsSep ",\n" cfg.extraActions}
],
};
'';
in
{
options.services.scanservjs = {
enable = lib.mkEnableOption "scanservjs";
stateDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/scanservjs";
description = ''
State directory for scanservjs.
'';
};
settings = lib.mkOption {
default = { };
description = ''
Config to set in config.local.js's `afterConfig`.
'';
type = lib.types.submodule {
freeformType = settingsFormat.type;
options.host = lib.mkOption {
type = lib.types.str;
description = "The IP to listen on.";
default = "127.0.0.1";
};
options.port = lib.mkOption {
type = lib.types.port;
description = "The port to listen on.";
default = 8080;
};
};
};
extraConfig = lib.mkOption {
default = "";
type = lib.types.lines;
description = ''
Extra code to add to config.local.js's `afterConfig`.
'';
};
extraDevicesConfig = lib.mkOption {
default = "";
type = lib.types.lines;
description = ''
Extra code to add to config.local.js's `afterDevices`.
'';
};
runAfterScan = lib.mkOption {
default = "";
type = lib.types.lines;
description = ''
Extra code to add to config.local.js's `afterScan`.
'';
};
extraActions = lib.mkOption {
default = [ ];
type = lib.types.listOf lib.types.lines;
description = "Actions to add to config.local.js's `actions`.";
};
};
config = lib.mkIf cfg.enable {
hardware.sane.enable = true;
users.users.scanservjs = {
group = "scanservjs";
extraGroups = [
"scanner"
"lp"
];
home = cfg.stateDir;
isSystemUser = true;
createHome = true;
};
users.groups.scanservjs = { };
systemd.services.scanservjs = {
description = "scanservjs";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
# yes, those paths are configurable, but the config option isn't always used...
# a lot of the time scanservjs just takes those from PATH
path = with pkgs; [
coreutils
config.hardware.sane.backends-package
imagemagick
tesseract
];
environment = {
NIX_SCANSERVJS_CONFIG_PATH = configFile;
SANE_CONFIG_DIR = "/etc/sane-config";
LD_LIBRARY_PATH = "/etc/sane-libs";
};
serviceConfig = {
ExecStart = lib.getExe package;
Restart = "always";
User = "scanservjs";
Group = "scanservjs";
WorkingDirectory = cfg.stateDir;
};
};
};
}