lol

scanservjs: init at 2.27.1; nixos/scanservjs: init (#249806)

authored by

Arne Keller and committed by
GitHub
0a324bb3 fe4fe1f7

+315
+2
nixos/doc/manual/release-notes/rl-2505.section.md
··· 16 16 17 17 - [Bazecor](https://github.com/Dygmalab/Bazecor), the graphical configurator for Dygma Products. 18 18 19 + - [scanservjs](https://github.com/sbs20/scanservjs/), a web UI for SANE scanners. Available at [services.scanservjs](#opt-services.scanservjs.enable). 20 + 19 21 - [Kimai](https://www.kimai.org/), a web-based multi-user time-tracking application. Available as [services.kimai](options.html#opt-services.kimai). 20 22 21 23 - [Omnom](https://github.com/asciimoo/omnom), a webpage bookmarking and snapshotting service. Available as [services.omnom](options.html#opt-services.omnom.enable).
+1
nixos/modules/module-list.nix
··· 624 624 ./services/hardware/sane_extra_backends/brscan4.nix 625 625 ./services/hardware/sane_extra_backends/brscan5.nix 626 626 ./services/hardware/sane_extra_backends/dsseries.nix 627 + ./services/hardware/scanservjs.nix 627 628 ./services/hardware/spacenavd.nix 628 629 ./services/hardware/supergfxd.nix 629 630 ./services/hardware/tcsd.nix
+155
nixos/modules/services/hardware/scanservjs.nix
··· 1 + { 2 + config, 3 + lib, 4 + pkgs, 5 + ... 6 + }: 7 + 8 + let 9 + cfg = config.services.scanservjs; 10 + settings = { 11 + scanimage = lib.getExe' config.hardware.sane.backends-package "scanimage"; 12 + convert = lib.getExe' pkgs.imagemagick "convert"; 13 + tesseract = lib.getExe pkgs.tesseract; 14 + # it defaults to config/devices.json, but "config" dir doesn't exist by default and scanservjs doesn't create it 15 + devicesPath = "devices.json"; 16 + } // cfg.settings; 17 + settingsFormat = pkgs.formats.json { }; 18 + 19 + leafs = 20 + attrs: 21 + builtins.concatLists ( 22 + lib.mapAttrsToList (k: v: if builtins.isAttrs v then leafs v else [ v ]) attrs 23 + ); 24 + 25 + package = pkgs.scanservjs; 26 + 27 + configFile = pkgs.writeText "config.local.js" '' 28 + /* eslint-disable no-unused-vars */ 29 + module.exports = { 30 + afterConfig(config) { 31 + ${ 32 + builtins.concatStringsSep "" ( 33 + leafs ( 34 + lib.mapAttrsRecursive (path: val: '' 35 + ${builtins.concatStringsSep "." path} = ${builtins.toJSON val}; 36 + '') { config = settings; } 37 + ) 38 + ) 39 + } 40 + ${cfg.extraConfig} 41 + }, 42 + 43 + afterDevices(devices) { 44 + ${cfg.extraDevicesConfig} 45 + }, 46 + 47 + async afterScan(fileInfo) { 48 + ${cfg.runAfterScan} 49 + }, 50 + 51 + actions: [ 52 + ${builtins.concatStringsSep ",\n" cfg.extraActions} 53 + ], 54 + }; 55 + ''; 56 + 57 + in 58 + { 59 + options.services.scanservjs = { 60 + enable = lib.mkEnableOption "scanservjs"; 61 + stateDir = lib.mkOption { 62 + type = lib.types.str; 63 + default = "/var/lib/scanservjs"; 64 + description = '' 65 + State directory for scanservjs. 66 + ''; 67 + }; 68 + settings = lib.mkOption { 69 + default = { }; 70 + description = '' 71 + Config to set in config.local.js's `afterConfig`. 72 + ''; 73 + type = lib.types.submodule { 74 + freeformType = settingsFormat.type; 75 + options.host = lib.mkOption { 76 + type = lib.types.str; 77 + description = "The IP to listen on."; 78 + default = "127.0.0.1"; 79 + }; 80 + options.port = lib.mkOption { 81 + type = lib.types.port; 82 + description = "The port to listen on."; 83 + default = 8080; 84 + }; 85 + }; 86 + }; 87 + extraConfig = lib.mkOption { 88 + default = ""; 89 + type = lib.types.lines; 90 + description = '' 91 + Extra code to add to config.local.js's `afterConfig`. 92 + ''; 93 + }; 94 + extraDevicesConfig = lib.mkOption { 95 + default = ""; 96 + type = lib.types.lines; 97 + description = '' 98 + Extra code to add to config.local.js's `afterDevices`. 99 + ''; 100 + }; 101 + runAfterScan = lib.mkOption { 102 + default = ""; 103 + type = lib.types.lines; 104 + description = '' 105 + Extra code to add to config.local.js's `afterScan`. 106 + ''; 107 + }; 108 + extraActions = lib.mkOption { 109 + default = [ ]; 110 + type = lib.types.listOf lib.types.lines; 111 + description = "Actions to add to config.local.js's `actions`."; 112 + }; 113 + }; 114 + 115 + config = lib.mkIf cfg.enable { 116 + hardware.sane.enable = true; 117 + users.users.scanservjs = { 118 + group = "scanservjs"; 119 + extraGroups = [ 120 + "scanner" 121 + "lp" 122 + ]; 123 + home = cfg.stateDir; 124 + isSystemUser = true; 125 + createHome = true; 126 + }; 127 + users.groups.scanservjs = { }; 128 + 129 + systemd.services.scanservjs = { 130 + description = "scanservjs"; 131 + after = [ "network.target" ]; 132 + wantedBy = [ "multi-user.target" ]; 133 + # yes, those paths are configurable, but the config option isn't always used... 134 + # a lot of the time scanservjs just takes those from PATH 135 + path = with pkgs; [ 136 + coreutils 137 + config.hardware.sane.backends-package 138 + imagemagick 139 + tesseract 140 + ]; 141 + environment = { 142 + NIX_SCANSERVJS_CONFIG_PATH = configFile; 143 + SANE_CONFIG_DIR = "/etc/sane-config"; 144 + LD_LIBRARY_PATH = "/etc/sane-libs"; 145 + }; 146 + serviceConfig = { 147 + ExecStart = lib.getExe package; 148 + Restart = "always"; 149 + User = "scanservjs"; 150 + Group = "scanservjs"; 151 + WorkingDirectory = cfg.stateDir; 152 + }; 153 + }; 154 + }; 155 + }
+64
pkgs/by-name/sc/scanservjs/decouple-from-source-tree.patch
··· 1 + diff --git a/packages/server/src/api.js b/packages/server/src/api.js 2 + index bd43842..71ce7c9 100644 3 + --- a/packages/server/src/api.js 4 + +++ b/packages/server/src/api.js 5 + @@ -105,7 +105,7 @@ module.exports = new class Api { 6 + } 7 + 8 + // If not then it's possible the default image is not quite the correct aspect ratio 9 + - const buffer = FileInfo.create(`${config.previewDirectory}/default.jpg`).toBuffer(); 10 + + const buffer = FileInfo.create('NIX_OUT_PLACEHOLDER/lib/node_modules/scanservjs-api/data/preview/default.jpg').toBuffer(); 11 + 12 + try { 13 + // We need to know the correct aspect ratio from the device 14 + diff --git a/packages/server/src/application.js b/packages/server/src/application.js 15 + index 2771036..0c2a4c0 100644 16 + --- a/packages/server/src/application.js 17 + +++ b/packages/server/src/application.js 18 + @@ -26,7 +26,7 @@ module.exports = new class Application { 19 + 20 + userOptions() { 21 + if (this._userOptions === null) { 22 + - this._userOptions = new UserOptions('../../config/config.local.js'); 23 + + this._userOptions = new UserOptions(process.env.NIX_SCANSERVJS_CONFIG_PATH); 24 + } 25 + return this._userOptions; 26 + } 27 + diff --git a/packages/server/src/classes/user-options.js b/packages/server/src/classes/user-options.js 28 + index f129e3c..c71e754 100644 29 + --- a/packages/server/src/classes/user-options.js 30 + +++ b/packages/server/src/classes/user-options.js 31 + @@ -4,7 +4,7 @@ const path = require('path'); 32 + module.exports = class UserOptions { 33 + constructor(localConfigPath) { 34 + if (localConfigPath) { 35 + - const localPath = path.join(__dirname, localConfigPath); 36 + + const localPath = localConfigPath; 37 + if (fs.existsSync(localPath)) { 38 + this.local = require(localPath); 39 + } 40 + diff --git a/packages/server/src/configure.js b/packages/server/src/configure.js 41 + index c9e5ed8..484949c 100644 42 + --- a/packages/server/src/configure.js 43 + +++ b/packages/server/src/configure.js 44 + @@ -71,6 +71,7 @@ function initialize(rootPath) { 45 + 46 + try { 47 + fs.mkdirSync(config.outputDirectory, { recursive: true }); 48 + + fs.mkdirSync(config.previewDirectory, { recursive: true }); 49 + fs.mkdirSync(config.tempDirectory, { recursive: true }); 50 + } catch (exception) { 51 + log.warn(`Error ensuring output and temp directories exist: ${exception}`); 52 + diff --git a/packages/server/src/server.js b/packages/server/src/server.js 53 + index e1a9fb0..3d58d37 100644 54 + --- a/packages/server/src/server.js 55 + +++ b/packages/server/src/server.js 56 + @@ -5,7 +5,7 @@ const configure = require('./configure'); 57 + const config = application.config(); 58 + const app = express(); 59 + 60 + -app.use(express.static('client')); 61 + +app.use(express.static('@client@')); 62 + 63 + configure(app); 64 +
+93
pkgs/by-name/sc/scanservjs/package.nix
··· 1 + { 2 + lib, 3 + fetchFromGitHub, 4 + buildNpmPackage, 5 + fetchNpmDeps, 6 + nodejs, 7 + substituteAll, 8 + }: 9 + 10 + let 11 + version = "2.27.1"; 12 + src = fetchFromGitHub { 13 + owner = "sbs20"; 14 + repo = "scanservjs"; 15 + # rev = "v${version}"; 16 + # 2.27.1 doesn't have a tag 17 + rev = "b15adc6f97fb152fd9819371bb1a9b8118baf55b"; 18 + hash = "sha256-ne9fEF/eurWPXzmJQzBn5jiy+JgxMWiCXsOdmu2fj6E="; 19 + }; 20 + 21 + depsHashes = { 22 + server = "sha256-M8t+TrE+ntZaI9X7hEel94bz34DPtW32n0KKMSoCfIs="; 23 + client = "sha256-C31WBYE8ba0t4mfKFAuYWrCZtSdN7tQIYmCflDRKuBM="; 24 + }; 25 + 26 + serverDepsForClient = fetchNpmDeps { 27 + inherit src nodejs; 28 + sourceRoot = "${src.name}/packages/server"; 29 + name = "scanservjs"; 30 + hash = depsHashes.server or lib.fakeHash; 31 + }; 32 + 33 + # static client files 34 + client = buildNpmPackage { 35 + pname = "scanservjs-client"; 36 + inherit version src nodejs; 37 + 38 + sourceRoot = "${src.name}/packages/client"; 39 + npmDepsHash = depsHashes.client or lib.fakeHash; 40 + 41 + preBuild = '' 42 + cd ../server 43 + chmod +w package-lock.json . /build/source/ 44 + npmDeps=${serverDepsForClient} npmConfigHook 45 + cd ../client 46 + ''; 47 + 48 + env.NODE_OPTIONS = "--openssl-legacy-provider"; 49 + 50 + dontNpmInstall = true; 51 + installPhase = '' 52 + mv /build/source/dist/client $out 53 + ''; 54 + }; 55 + 56 + in 57 + buildNpmPackage { 58 + pname = "scanservjs"; 59 + inherit version src nodejs; 60 + 61 + sourceRoot = "${src.name}/packages/server"; 62 + npmDepsHash = depsHashes.server or lib.fakeHash; 63 + 64 + # can't use "patches" since they change the server deps' hash for building the client 65 + # (I don't want to maintain one more hash) 66 + preBuild = '' 67 + chmod +w /build/source 68 + patch -p3 <${ 69 + substituteAll { 70 + src = ./decouple-from-source-tree.patch; 71 + inherit client; 72 + } 73 + } 74 + substituteInPlace src/api.js --replace 'NIX_OUT_PLACEHOLDER' "$out" 75 + ''; 76 + 77 + postInstall = '' 78 + mkdir -p $out/bin 79 + makeWrapper ${lib.getExe nodejs} $out/bin/scanservjs \ 80 + --set NODE_ENV production \ 81 + --add-flags "'$out/lib/node_modules/scanservjs-api/src/server.js'" 82 + ''; 83 + 84 + meta = { 85 + description = "SANE scanner nodejs web ui"; 86 + longDescription = "scanservjs is a simple web-based UI for SANE which allows you to share a scanner on a network without the need for drivers or complicated installation."; 87 + homepage = "https://github.com/sbs20/scanservjs"; 88 + license = lib.licenses.gpl2Only; 89 + mainProgram = "scanservjs"; 90 + maintainers = with lib.maintainers; [ chayleaf ]; 91 + platforms = lib.platforms.linux; 92 + }; 93 + }