Skip to content

Commit

Permalink
Merge pull request #362 from sbs20/staging
Browse files Browse the repository at this point in the history
Localisation and optional geometry
  • Loading branch information
sbs20 authored Oct 3, 2021
2 parents c36cabc + 965d5cb commit 89192b9
Show file tree
Hide file tree
Showing 31 changed files with 667 additions and 273 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ on:
branches:
- 'master'
- 'staging'
tags:
- 'v*'
release:
types: [published]

jobs:
docker:
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ RUN apt-get update \
&& sed -i \
's/policy domain="coder" rights="none" pattern="PDF"/policy domain="coder" rights="read | write" pattern="PDF"'/ \
/etc/ImageMagick-6/policy.xml \
&& sed -i \
's/policy domain="resource" name="disk" value="1GiB"/policy domain="resource" name="disk" value="8GiB"'/ \
/etc/ImageMagick-6/policy.xml \
&& npm install -g [email protected]

# Create a known user
Expand Down
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ Copyright 2016-2021 [Sam Strachan](https://github.com/sbs20)
> broken, meaning the device is useless by itself because one cannot trigger
> scans, but with this project I can trigger it remotely just fine.

> Absolutely love untethering my scanner from my laptop. Also means that I know
> it will work "forever", regardless of OS updates, since its all just a docker
> container.
## About

scanservjs is a web UI frontend for your scanner. It allows you to share one or
Expand All @@ -42,8 +47,8 @@ complicated installation.
* Filters: Autolevels, Threshold, Blur
* Configurable overrides for all defaults as well as filters and formats
* Multipage scanning (with collation for double sided scans)
* International translations: Czech, French, German, Italian, Mandarin, Polish,
Portuguese (BR), Russian, Spanish;
* International translations: Czech, Dutch, French, German, Italian, Mandarin,
Polish, Portuguese (BR), Russian, Spanish;
[Help requested](https://github.com/sbs20/scanservjs/issues/154)
* Light and dark mode
* Responsive design
Expand All @@ -57,20 +62,16 @@ It supports any
* Linux host (or VM with necessary pass-through e.g. USB)
* Software sane-utils, ImageMagick, Tesseract (optional) and nodejs

## Installation
## Documentation

* [Manual installation](docs/install.md)
* [Docker installation](docs/docker.md)
* [Scanner and SANE setup](docs/sane.md)
* [Proxy setup](docs/proxy.md)
* [Troubleshooting](docs/troubleshooting.md)
* [Development notes](docs/development.md)

## Configuration and device override

If you want to override some specific configuration settings then you can do so
within `./config/config.local.js`. See [Configuration](docs/config.md) for more
detail.
* [Configuration and device override](docs/config.md)
* [Integration](docs/integration.md)

## Why?

Expand Down
3 changes: 2 additions & 1 deletion docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## One line install

* If you don't already have your scanner working, then you need to get
* If you don't already have your scanner working, then you must get
[SANE installed and working](./sane.md) and check permissions etc. Your
scanner can be attached to a different server / device if you're using saned.
* If you're using a debian based distro then you can just use the installer
Expand All @@ -11,6 +11,7 @@
```sh
curl -s https://raw.githubusercontent.com/sbs20/scanservjs/master/packages/server/installer.sh | sudo bash -s -- -a
```
Note: the installer script will always install from the master branch.
* If you're using Arch, then [@dadosch](https://github.com/dadosch) created a
PKGBUILD script in Arch's AUR which allows Arch-distro-based users to quickly
install and update scanservjs with any AUR helper, for example:
Expand Down
63 changes: 63 additions & 0 deletions docs/integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Integration

It's not uncommon to want to integrate scanservjs with other software - you may
wish to upload scans to Dropbox, paperless-ng or some other location. The
possibilities are endless and deep integration into the UI would add cruft for
the vast majority of users.

Thankfully, the files just end up in a location on your filesystem so you are
free to integrate however you want.

The recommended way is to create a script or program which scans the output
directory for files and then does something with them.

## paperless-ng

[This discussion](https://github.com/sbs20/scanservjs/issues/351#issuecomment-913858423)
about paperless-ng resulted in
[scantopl](https://github.com/Celedhrim/scantopl)

## Dropbox

You could integrate with Dropbox using
[Dropbox-Uploader](https://github.com/andreafabrizi/Dropbox-Uploader)

## Scan2Mail

1. Setup and configure [msmtp](https://wiki.debian.org/msmtp) and msmtp-mta as
described
[here](https://decatec.de/linux/linux-einfach-e-mails-versenden-mit-msmtp/)
2. Install the MIME packer [mpack](https://linux.die.net/man/1/mpack) with
`sudo apt install mpack` to send the scanned files
3. Setup [OCRmyPDF](https://github.com/jbarlow83/OCRmyPDF) as described
[here](https://ocrmypdf.readthedocs.io/en/latest/installation.html)

Now create the following pipeline in your `config/config.local.js`

```javascript
config.pipelines.push({
extension: 'pdf',
description: 'ocrmypdf (Scan2Mail [email protected])',
get commands() {
return [
'convert @- -quality 92 tmp-%04d.jpg && ls tmp-*.jpg',
'convert @- pdf:-',
`file="scan_$(date +"%d_%m_%Y-%H_%M").pdf" && ocrmypdf -l ${config.ocrLanguage} --deskew --rotate-pages --force-ocr - "$file" && mpack -s "Document from Scanner@Office" "$file" [email protected]`,
'ls scan_*.*'
];
}
});
```

The important `Scan2Mail` line is:

```
file="scan_$(date +"%d_%m_%Y-%H_%M").pdf" && ocrmypdf -l ${config.ocrLanguage} --deskew --rotate-pages --force-ocr - "$file" && mpack -s "Document from Scanner@Office" "$file" [email protected]
```

This sets a time-based filename, then OCRs and finally sends to
[email protected]

## Other recipes?

If you have other recipes then please share them.
4 changes: 2 additions & 2 deletions docs/proxy.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
## Reverse proxy
# Reverse proxy

scanservjs supports reverse proxying and uses relative paths throughout so no
URL rewriting should be required.

### Apache
## Apache

Example setup using a debian based distro.

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "scanservjs",
"version": "2.17.1",
"version": "2.18.0",
"description": "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.",
"scripts": {
"clean": "rm -rf ./dist",
Expand Down
4 changes: 2 additions & 2 deletions packages/client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "scanservjs",
"version": "2.17.1",
"version": "2.18.0",
"description": "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.",
"author": "Sam Strachan",
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/classes/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const Constants = {
'es',
'fr',
'it',
'nl',
'pl',
'pt-BR',
'ru',
Expand Down
10 changes: 6 additions & 4 deletions packages/client/src/classes/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ export default class Request {
version: Constants.Version,
params: {
deviceId: device.id,
top: request.params.top || device.features['-t'].default,
left: request.params.left || device.features['-l'].default,
width: request.params.width || device.features['-x'].default,
height: request.params.height || device.features['-y'].default,
resolution: request.params.resolution || device.features['--resolution'].default
},
filters: request.filters || [],
Expand All @@ -28,6 +24,12 @@ export default class Request {
index: 1
};

if (['-x', '-y', '-l', '-t'].every(s => s in device.features)) {
obj.params.top = request.params.top || device.features['-t'].default;
obj.params.left = request.params.left || device.features['-l'].default;
obj.params.width = request.params.width || device.features['-x'].default;
obj.params.height = request.params.height || device.features['-y'].default;
}
if ('--mode' in device.features) {
obj.params.mode = request.params.mode || device.features['--mode'].default;
}
Expand Down
51 changes: 30 additions & 21 deletions packages/client/src/components/Scan.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,36 +52,39 @@

<div class="d-flex flex-row-reverse flex-wrap">
<v-btn color="primary" @click="scan(1)" class="ml-1 mb-1">{{ $t('scan.btn-scan') }} <v-icon class="ml-2">mdi-camera</v-icon></v-btn>
<v-btn color="green" @click="createPreview" class="ml-1 mb-1">{{ $t('scan.btn-preview') }} <v-icon class="ml-2">mdi-magnify</v-icon></v-btn>
<v-btn v-if="geometry" color="green" @click="createPreview" class="ml-1 mb-1">{{ $t('scan.btn-preview') }} <v-icon class="ml-2">mdi-magnify</v-icon></v-btn>
<v-btn color="amber" @click="deletePreview" class="ml-1 mb-1">{{ $t('scan.btn-clear') }} <v-icon class="ml-2">mdi-delete</v-icon></v-btn>
</div>
</v-col>

<v-col cols="12" md="auto" class="mb-10 mb-md-0" :style="{width: `${preview.width}px`}">
<cropper ref="cropper" class="cropper" :key="preview.key" :transitionTime="10" :wheelResize="false"
<cropper v-if="geometry" ref="cropper" class="cropper" :key="preview.key" :transitionTime="10" :wheelResize="false"
:default-position="cropperDefaultPosition" :default-size="cropperDefaultSize"
:src="img" @change="onCropperChange"></cropper>
<v-img v-if="!geometry" :src="img" />
</v-col>

<v-col cols="12" md="3" class="mb-10 mb-md-0">
<v-text-field :label="$t('scan.top')" type="number" step="any" v-model="request.params.top" @blur="onCoordinatesChange" />
<v-text-field :label="$t('scan.left')" type="number" step="any" v-model="request.params.left" @blur="onCoordinatesChange" />
<v-text-field :label="$t('scan.width')" type="number" step="any" v-model="request.params.width" @blur="onCoordinatesChange" />
<v-text-field :label="$t('scan.height')" type="number" step="any" v-model="request.params.height" @blur="onCoordinatesChange" />

<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn color="primary" v-bind="attrs" v-on="on">{{ $t('scan.paperSize') }}</v-btn>
</template>
<v-list dense>
<v-list-item
v-for="(item, index) in paperSizes"
@click="updatePaperSize(item)"
:key="index">
<v-list-item-title>{{ item.name }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<template v-if="geometry">
<v-text-field :label="$t('scan.top')" type="number" step="any" v-model="request.params.top" @blur="onCoordinatesChange" />
<v-text-field :label="$t('scan.left')" type="number" step="any" v-model="request.params.left" @blur="onCoordinatesChange" />
<v-text-field :label="$t('scan.width')" type="number" step="any" v-model="request.params.width" @blur="onCoordinatesChange" />
<v-text-field :label="$t('scan.height')" type="number" step="any" v-model="request.params.height" @blur="onCoordinatesChange" />

<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn color="primary" v-bind="attrs" v-on="on">{{ $t('scan.paperSize') }}</v-btn>
</template>
<v-list dense>
<v-list-item
v-for="(item, index) in paperSizes"
@click="updatePaperSize(item)"
:key="index">
<v-list-item-title>{{ item.name }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</template>

<div v-if="'--brightness' in device.features">
<v-slider class="align-center" v-model="request.params.brightness"
Expand Down Expand Up @@ -180,6 +183,10 @@ export default {
},
computed: {
geometry() {
return ['-x', '-y', '-l', '-t'].every(s => s in this.device.features);
},
deviceSize() {
return {
width: this.device.features['-x'].limits[1],
Expand Down Expand Up @@ -272,7 +279,9 @@ export default {
methods: {
_resizePreview() {
const paperRatio = this.deviceSize.width / this.deviceSize.height;
const paperRatio = this.geometry
? this.deviceSize.width / this.deviceSize.height
: 210 / 297;
// This only makes a difference when the col-width="auto" - so md+
const mdBreakpoint = 960;
Expand Down
Loading

0 comments on commit 89192b9

Please sign in to comment.