diff --git a/Dockerfile b/Dockerfile index 84716077..8652931d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,22 +5,38 @@ WORKDIR "$APP_DIR" COPY package*.json "$APP_DIR/" RUN npm install COPY . "$APP_DIR" -RUN npm run server-build -RUN npm run client-build +RUN npm run server-build && npm run client-build # production image FROM node:buster-slim ENV APP_DIR=/app WORKDIR "$APP_DIR" -# Install sane -RUN apt-get update && apt-get install -yq sane sane-utils imagemagick tesseract-ocr -RUN sed -i 's/policy domain="coder" rights="none" pattern="PDF"/policy domain="coder" rights="read | write" pattern="PDF"'/ /etc/ImageMagick-6/policy.xml COPY --from=builder "$APP_DIR/dist" "$APP_DIR/" -# Install dependencies +RUN apt-get update && \ + apt-get install -yq curl gpg && \ + echo 'deb http://download.opensuse.org/repositories/home:/pzz/Debian_10/ /' | tee /etc/apt/sources.list.d/home:pzz.list && \ + curl -fsSL https://download.opensuse.org/repositories/home:pzz/Debian_10/Release.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/home:pzz.gpg > /dev/null && \ + apt-get update && \ + apt-get install -yq sane sane-utils imagemagick tesseract-ocr sane-airscan && \ + sed -i 's/policy domain="coder" rights="none" pattern="PDF"/policy domain="coder" rights="read | write" pattern="PDF"'/ /etc/ImageMagick-6/policy.xml + RUN npm install --production -ENV NET_HOST="" +# This goes into /etc/sane.d/net.conf +ENV SANED_NET_HOSTS="" + +# This gets added to /etc/sane.d/airscan.conf +ENV AIRSCAN_DEVICES="" + +# This directs scanserv not to bother querying `scanimage -L` +ENV SCANIMAGE_LIST_IGNORE="" + +# This gets added to scanservjs/config/config.js:devices +ENV DEVICES="" + +# Override OCR language +ENV OCR_LANG="" # Copy entry point COPY run.sh /run.sh diff --git a/client/components/Scanserv.vue b/client/components/Scanserv.vue index 7cd6ff24..8ac80c81 100644 --- a/client/components/Scanserv.vue +++ b/client/components/Scanserv.vue @@ -381,13 +381,21 @@ export default { return this._fetch(url).then(context => { this.context = context; - this.device = context.devices[0]; - this.$refs.toastr.i(`Found device ${this.device.id}`); - this.request = this.readRequest(); - for (let test of context.diagnostics) { - const toast = test.success ? this.$refs.toastr.s : this.$refs.toastr.e; - toast(test.message); + + if (context.devices.length > 0) { + for (let device of context.devices) { + this.$refs.toastr.i(`Found device ${device.id}`); + } + this.device = context.devices[0]; + this.request = this.readRequest(); + for (let test of context.diagnostics) { + const toast = test.success ? this.$refs.toastr.s : this.$refs.toastr.e; + toast(test.message); + } + } else { + this.$refs.toastr.e('Found no devices'); } + if (force) { this.clear(); this.readPreview(); diff --git a/config/config.js b/config/config.js index 7d438a6d..ea5f01af 100644 --- a/config/config.js +++ b/config/config.js @@ -5,9 +5,6 @@ const Config = {}; // Things to change Config.port = 8080; -// scanservjs will attempt to find scanners locally using `scanimage -L` but you -// will need to manually add network devices here which will be appended. e.g. -// Config.devices = ['net:192.168.0.10:airscan:e0:Canon TR8500 series']; Config.devices = []; Config.ocrLanguage = 'eng'; Config.log = {}; @@ -177,4 +174,27 @@ if (Config.tesseract) { ]); } +// Process environment variables + +// scanservjs will attempt to find scanners locally using `scanimage -L` but +// sometimes you may need to manually add network devices here if they're not +// found e.g. +// Config.devices = ['net:192.168.0.10:airscan:e0:Canon TR8500 series']; +// This is done with an environment variable. Multiple entries are separated by +// semicolons +if (process.env.DEVICES !== undefined && process.env.DEVICES.length > 0) { + Config.devices = process.env.DEVICES.split(';'); +} + +// scanservjs will attempt to find scanners locally using `scanimage -L` but +// sometimes it will return nothing. If you are specifying devices manually you +// may also with to turn off the find. +Config.devicesFind = process.env.SCANIMAGE_LIST_IGNORE === undefined + || process.env.SCANIMAGE_LIST_IGNORE.length === 0; + +// Override the OCR language here +if (process.env.OCR_LANG !== undefined && process.env.OCR_LANG.length > 0) { + Config.ocrLanguage = process.env.OCR_LANG; +} + module.exports = Config; diff --git a/docs/development.md b/docs/development.md index a7e49d91..32e3ff26 100644 --- a/docs/development.md +++ b/docs/development.md @@ -54,6 +54,10 @@ gulp release Install docker ``` sudo apt install docker.io +sudo systemctl unmask docker +sudo systemctl start docker + +# Hack to make docker accessible. sudo chmod 666 /var/run/docker.sock ``` diff --git a/run.sh b/run.sh index cef28ccd..8e973bd9 100644 --- a/run.sh +++ b/run.sh @@ -1,5 +1,31 @@ #!/bin/sh set -xve -[ ! -z "$NET_HOST" ] && echo $NET_HOST > /etc/sane.d/net.conf + +# turn off globbing +set -f + +# split at newlines only (airscan devices can have spaces in) +IFS=' +' + +# Insert a list of net hosts +if [ ! -z "$SANED_NET_HOSTS" ]; then + hosts=$(echo $SANED_NET_HOSTS | sed "s/;/\n/") + for host in $hosts; do + echo $host >> /etc/sane.d/net.conf + done +fi + +# Insert airscan devices +if [ ! -z "$AIRSCAN_DEVICES" ]; then + devices=$(echo $AIRSCAN_DEVICES | sed "s/;/\n/") + for device in $devices; do + sed -i "/^\[devices\]/a $device" /etc/sane.d/airscan.conf + done +fi + +unset IFS +set +f + node ./server/server.js diff --git a/server/devices.js b/server/devices.js index 34ea5ded..1b9a2858 100644 --- a/server/devices.js +++ b/server/devices.js @@ -56,14 +56,17 @@ class Devices { } if (devices === null) { - let data = await Process.execute(Scanimage.devices()); - log.debug('Device list: ', data); - const localDevices = Devices._parseDevices(data); - const deviceIds = localDevices.concat(Config.devices); + let deviceIds = Config.devices; + if (Config.devicesFind) { + const data = await Process.execute(Scanimage.devices()); + log.debug('Device list: ', data); + const localDevices = Devices._parseDevices(data); + deviceIds = deviceIds.concat(localDevices); + } devices = []; for (let deviceId of deviceIds) { - data = await Process.execute(Scanimage.features(deviceId)); + const data = await Process.execute(Scanimage.features(deviceId)); log.debug('Device features: ', data); devices.push(Device.from(data)); }