Compare commits

..
Author SHA1 Message Date
Jonas Winkler 5612ad08dd New Crowdin updates (#1305) 2021-09-14 21:34:53 +02:00
Jonas Winkler e9956234a3 Merge pull request #1297 from shamoon/feature/issue-1260
Add loading indicator when document list reloading
2021-09-10 20:37:37 +02:00
Jonas Winkler 73700437e4 New Crowdin updates (#1276) 2021-09-10 20:34:33 +02:00
Michael Shamoon 14d96350c3 Add i18n 2021-09-10 11:28:49 -07:00
Michael Shamoon 097fe424c2 Show loading with spinner on document list reloading 2021-09-08 21:12:44 -07:00
Jonas Winkler b555b3664f Merge pull request #1262 from Tooa/fix-issue-1250
fix(tika): adapt to Gotenberg 7 API
2021-08-28 13:57:23 +02:00
Uli Fahrer 2dcacaee14 fix(tika): adapt to Gotenberg 7 API
This commit adapts to the latest breaking changes from Gotenberg 7.
It also freezes the usage of the Gotenberg server to v7.x. Doing
this prevents further breaking changes leaking in our code base.

* refs #1250
2021-08-27 08:32:16 +02:00
jonaswinkler cd43bc1f66 changelog 2021-08-22 17:15:14 +02:00
jonaswinkler 1b24136590 version bump 2021-08-22 17:11:36 +02:00
jonaswinkler e8d5b549de documentation 2021-08-22 17:10:10 +02:00
jonaswinkler 3866a77d68 Merge branch 'master' into dev 2021-08-22 17:03:58 +02:00
jonaswinkler 360fe68f92 fix whitespace 2021-08-22 17:03:45 +02:00
Jonas Winkler c9229f9c80 Merge pull request #1066 from holzhannes/patch-3
Info for The input device is not a TTY Errors
2021-08-22 17:02:08 +02:00
Jonas WinklerandStéphane Brunner e5b92d895d Update docs/administration.rst
Co-authored-by: Stéphane Brunner <stephane.brunner@camptocamp.com>
2021-08-22 17:00:36 +02:00
jonaswinkler a7643c1c29 Merge branch 'master' into dev 2021-08-22 16:27:59 +02:00
jonaswinkler 45fd4e8565 fix whitespace 2021-08-22 16:27:44 +02:00
jonaswinkler 211a9d720a changelog 2021-08-22 16:26:58 +02:00
Jonas Winkler da9c2735b4 Merge pull request #1201 from pewter77/patch-1
update configuration docs for languages
2021-08-22 16:26:27 +02:00
jonaswinkler d31baca442 downgrade numpy due to armv7 issues 2021-08-19 16:18:49 +02:00
jonaswinkler 499d6f79aa Merge remote-tracking branch 'origin/master' into dev 2021-08-19 00:06:47 +02:00
jonaswinkler 49e049f1c5 Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-08-19 00:06:37 +02:00
jonaswinkler 7411d7c1e2 update dependencies 2021-08-19 00:06:23 +02:00
Jonas Winkler 3f5d3d15fd Merge pull request #1209 from Unkn0wnCat/patch-1
Add Doxie Q to scanners.rst
2021-08-18 23:53:14 +02:00
Jonas Winkler 68fb85ceca Merge pull request #1221 from AlD/master
Make ignores configurable
2021-08-18 22:41:27 +02:00
Daniel Albers 3ebe6d5aef Make ignores configurable
Adds config file setting PAPERLESS_CONSUMER_IGNORE_PATTERNS.
2021-08-18 22:23:18 +02:00
jonaswinkler 566b3ed53d Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-08-18 22:03:31 +02:00
Jonas Winkler a688c747d7 New Crowdin updates (#1198) 2021-08-18 21:56:59 +02:00
jonaswinkler 83b90e1416 install required dependency for building paperless-ng on GitHub CI 2021-08-18 18:40:27 +02:00
jonaswinkler 23c6f849d6 fix bug with DPI calculation 2021-08-18 18:33:33 +02:00
jonaswinkler ba6843df83 update python dependencies 2021-08-18 18:21:41 +02:00
jonaswinkler 0b90e69119 update dockerfile 2021-08-18 18:21:31 +02:00
jonaswinkler dbe820323e switch to python 3.9 2021-08-18 17:47:53 +02:00
Kevin Kandlbinder 47d95d5b0a Add Doxie Q to scanners.rst
The Doxie Q / Q2 is a budget-scanner I've been using for my paperless-usage. It has POST-Support to a custom endpoint like paperless over WiFi and has a rather open API (See https://help.getdoxie.com/doxieq/wifi/api/).
2021-08-04 15:23:12 +02:00
pewter77 971192f6f3 update configuration docs for languages
Due to tesseract naming scheme, packages use '-' but the internal OCR uses '_' . This is to clarify in the documentation that this is the case for new users.
2021-07-30 23:21:22 +08:00
Jonas Winkler fbfc7df593 Merge pull request #1173 from mweimerskirch/feature/l10n-lb_LU
Added support for Luxembourgish (lb_LU) as an interface language
2021-07-18 21:42:58 +02:00
Jonas Winkler 3c7644ce79 Merge pull request #1153 from jonaswinkler/l10n_dev
New Crowdin updates
2021-07-18 17:36:14 +02:00
Jonas Winkler 4e4a8bcca8 New translations messages.xlf (Luxembourgish)
[ci skip]
2021-07-16 17:20:14 +02:00
Michel Weimerskirch dc5586b16d Added support for Luxembourgish (lb_LU) as an interface language 2021-07-16 16:43:55 +02:00
Jonas Winkler 1d87b48471 New translations messages.xlf (Luxembourgish)
[ci skip]
2021-07-16 16:22:10 +02:00
Jonas Winkler 353a3432df New translations django.po (Luxembourgish)
[ci skip]
2021-07-16 16:22:08 +02:00
Jonas Winkler efe94bbf18 New translations messages.xlf (Luxembourgish)
[ci skip]
2021-07-16 15:01:08 +02:00
Jonas Winkler cea6ec09bc New translations django.po (Luxembourgish)
[ci skip]
2021-07-16 15:01:07 +02:00
Jonas Winkler 4a3276f69c New translations messages.xlf (Luxembourgish)
[ci skip]
2021-07-16 13:47:43 +02:00
Jonas Winkler f164def2ed New translations django.po (Luxembourgish)
[ci skip]
2021-07-16 13:47:42 +02:00
Jonas Winkler 511c76ae7a New translations messages.xlf (Luxembourgish)
[ci skip]
2021-07-15 10:58:18 +02:00
Jonas Winkler bfa6dda0de New translations django.po (Luxembourgish)
[ci skip]
2021-07-15 10:58:16 +02:00
Jonas Winkler 54af734971 New translations django.po (Luxembourgish)
[ci skip]
2021-07-15 09:42:47 +02:00
Jonas Winkler 5b9763ecb4 New translations messages.xlf (Luxembourgish)
[ci skip]
2021-07-14 18:00:31 +02:00
Jonas Winkler 438bad23e8 New translations django.po (Luxembourgish)
[ci skip]
2021-07-14 18:00:29 +02:00
Jonas Winkler ae5a205ba3 New translations django.po (Luxembourgish)
[ci skip]
2021-07-14 10:42:55 +02:00
Jonas Winkler 19b683e7b0 New translations messages.xlf (Luxembourgish)
[ci skip]
2021-07-13 23:45:12 +02:00
Jonas Winkler 0c92027414 New translations django.po (Luxembourgish)
[ci skip]
2021-07-13 23:45:11 +02:00
Jonas Winkler c4e3b2ca2f New translations messages.xlf (Luxembourgish)
[ci skip]
2021-07-13 22:18:15 +02:00
Jonas Winkler ba67b89db7 New translations django.po (Luxembourgish)
[ci skip]
2021-07-13 22:18:14 +02:00
Jonas Winkler 06f308ede3 New translations messages.xlf (Spanish)
[ci skip]
2021-07-11 12:20:36 +02:00
Jonas Winkler 214fb8204b New translations messages.xlf (Spanish)
[ci skip]
2021-07-11 10:29:21 +02:00
Jonas Winkler 2a2d7be9f9 New translations django.po (Spanish)
[ci skip]
2021-07-11 10:29:20 +02:00
Jonas Winkler 23304c3746 New translations django.po (Spanish)
[ci skip]
2021-07-11 09:21:44 +02:00
Jonas Winkler 20829c90b2 New translations django.po (German)
[ci skip]
2021-07-05 13:17:50 +02:00
Jonas Winkler 33cc3ce7e0 Merge pull request #1127 from jonaswinkler/l10n_dev
New Crowdin updates
2021-07-04 12:47:07 +02:00
Jonas Winkler 3487b23e88 New translations django.po (English, United Kingdom)
[ci skip]
2021-06-19 23:20:13 +02:00
Jonas Winkler 4718fe13c2 Merge pull request #1116 from ytzelf/patch-1
Update scanners.rst
2021-06-14 18:18:57 +02:00
ytzelf 8592acf6b8 Update scanners.rst
Added ADS-1100w which has FTP (and only FTP) capabilities but is quite cheap
2021-06-14 18:11:06 +02:00
jonaswinkler 88042d7072 fix wording 2021-06-13 21:30:20 +02:00
jonaswinkler bf92e52d5c update dependencies 2021-06-13 21:21:56 +02:00
jonaswinkler 419580b3be changelog, versions 2021-06-13 19:17:29 +02:00
jonaswinkler 5ee1f6b82b Merge branch 'normalize-whitespace' into dev 2021-06-13 19:06:08 +02:00
Michael Lynch 410bb6a84e Fix trailing newlines in configuration.rst 2021-06-13 10:57:58 -04:00
Michael Lynch af2b5fef13 Add checkout step to whitespace CI job 2021-06-13 10:57:40 -04:00
Michael Lynch 372ac3a40c Normalize whitespace in source files
Ensure that no source files have trailing whitespace at end of lines and ensure that all files end with a single trailing newline.

This also adds Github Actions to enforce whitespace conventions.
2021-06-13 10:57:40 -04:00
jonaswinkler a1507d6079 update django-q 2021-06-13 16:36:05 +02:00
jonaswinkler 9242a8901a update django-q 2021-06-13 15:43:32 +02:00
jonaswinkler 1d4f25f930 update datepipe implementation due to interface change 2021-06-13 15:27:04 +02:00
jonaswinkler 7323ec8d16 update angular devkit 2021-06-13 15:18:23 +02:00
jonaswinkler 39d45367d0 replace ng-bootstrap with ngx-bootstrap 2021-06-13 15:12:56 +02:00
jonaswinkler a6521952b0 update to Angular 11 2021-06-13 15:08:56 +02:00
jonaswinkler 7148c10f1b update docker entrypoint 2021-06-13 12:54:24 +02:00
jonaswinkler 4a1a66248d update requirements.txt 2021-06-13 12:40:28 +02:00
Jonas Winkler 67d0773231 Merge pull request #933 from sbrunner/suggest
Add suggest
2021-06-13 12:20:34 +02:00
jonaswinkler ff370172b5 fix pycodestyle 2021-06-13 12:18:21 +02:00
jonaswinkler 1f707e86cc fix logging getting spammed with pdfminer warnings on JPG files 2021-06-13 12:09:16 +02:00
jonaswinkler a3dae02cfb write classifier model to temporary file before copying to final location 2021-06-13 12:03:20 +02:00
jonaswinkler 3eae8a2210 update dependencies 2021-06-13 12:02:49 +02:00
Jonas Winkler 0f18fe1853 Merge pull request #1107 from MJWcodr/patch-1
Update setup.rst
2021-06-13 11:34:03 +02:00
Jonas Winkler 513c61eb79 Merge pull request #1113 from magnetic6/master
Document specification of the expected creation date order
2021-06-13 11:33:43 +02:00
Peter M 4031233fd4 Document specification of the expected creation date order 2021-06-12 10:15:51 -04:00
Matthias J. Wünsch 76ff6100a3 Update setup.rst 2021-06-09 16:46:53 +02:00
Jonas Winkler 05c36f91cf Merge pull request #1105 from mtlynch/single-install-cmd
Simplify installation command
2021-06-07 00:48:29 +02:00
Michael Lynch 6625f8962a Simplify installation command
The installation for docker is currently three separate commands, but it can be a single command if the user simply pipes to the sh interpreter directly. I know there are some who object to piping to sh from a URL, but the current method has no security benefit over piping directly to sh.
2021-06-06 18:02:23 -04:00
Jonas Winkler 63402b70d2 Merge pull request #1057 from muued/patch-6
adjust ansible README to installation instructions
2021-06-03 15:14:36 +02:00
Stéphane Brunner 2ae4a7806d Add suggest 2021-05-30 14:50:29 +02:00
Jonas Winkler fcc4ecd007 Merge pull request #1068 from servusoft/dev
Solving issue with search criteria 'maximum age' for some mail server
2021-05-29 19:13:10 +02:00
Jonas Winkler 45497250cd Merge pull request #1074 from sbrunner/scan-to-paperless
Add Scan to Paperless as affiliated project
2021-05-29 19:12:46 +02:00
Stéphane Brunner 7dd957140e Add Scan to Paperless as affiliated project 2021-05-29 16:38:16 +02:00
servusoft 4cd772a39e Solving issue with search criteria maximum age for some mail server
Some mail servers (mail.ru) do not support search criteria for the maximum age. By setting the maximum age to 0, it is possible to hide the search criteria. This PR solves that problem.
2021-05-27 18:30:57 +02:00
HolzHannes b3906e7bc1 Corrected position of info 2021-05-27 10:01:30 +02:00
HolzHannes e5009b4cd2 Info for The input device is not a TTY Errors 2021-05-27 08:30:21 +02:00
Fabian Ohler 10bf9fd1f8 Adjusted paperlessng_version variable explanation 2021-05-26 08:30:17 +02:00
Jonas Winkler bd8e68692e New translations django.po (Dutch) (#1048) 2021-05-25 00:01:38 +02:00
Jonas Winkler b8386a1531 Merge pull request #1052 from muued/patch-5
Use ansible-galaxy during updates
2021-05-25 00:01:20 +02:00
Fabian OhlerandFabian Koller 61534fb29d Apply suggestions from code review
Co-authored-by: Fabian Koller <C0nsultant@users.noreply.github.com>
2021-05-24 15:27:11 +02:00
Fabian Ohler 9ad81be38c adjust ansible README to installation instructions
and fix some typos
2021-05-24 15:10:41 +02:00
Fabian Ohler cf7048e336 Use ansible-galaxy during updates
This mechanism is already used for the installation process.
2021-05-22 23:29:44 +02:00
jonaswinkler a6105b3ad3 update frontend dependencies 2021-05-21 15:27:10 +02:00
jonaswinkler a262a82cad Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-05-19 23:11:43 +02:00
jonaswinkler 635c96accf better exception handling 2021-05-19 23:11:24 +02:00
Jonas Winkler 5c174a69c2 New Crowdin updates (#1043) 2021-05-19 23:00:51 +02:00
jonaswinkler de08d17835 changelog 2021-05-19 23:00:03 +02:00
jonaswinkler ca1e838c52 catch another exception regarding classifier loading 2021-05-19 22:57:52 +02:00
jonaswinkler 3b73146ecd changelog and version bump 2021-05-19 22:40:56 +02:00
jonaswinkler 8e3822f8e6 Merge remote-tracking branch 'origin/master' into dev 2021-05-19 22:37:01 +02:00
jonaswinkler 3b912a0de1 improved docker startup time 2021-05-19 22:26:51 +02:00
jonaswinkler c72791bd21 Fix file permissions 2021-05-19 22:05:23 +02:00
jonaswinkler 80ba5b561f codestyle 2021-05-19 20:26:12 +02:00
jonaswinkler f9f4d4c937 Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-05-19 20:03:05 +02:00
jonaswinkler 0419c52d35 fix file permissions 2021-05-19 20:02:56 +02:00
jonaswinkler 93a79be1e2 delete macOS specific files 2021-05-19 20:02:47 +02:00
jonaswinkler f8afbae2cd ignore macOS specific files 2021-05-19 19:56:01 +02:00
jonaswinkler 4a52d346f9 remove dead code 2021-05-19 19:55:35 +02:00
Jonas Winkler 7d59d11725 New Crowdin updates (#1026) 2021-05-18 14:46:12 +02:00
Jonas Winkler 5886348188 Merge pull request #1034 from steviehs/patch-1
Update setup.rst
2021-05-18 14:45:52 +02:00
steviehs a8135528b1 Update setup.rst
Added hint to upgrade pip first.
2021-05-17 09:07:31 +02:00
jonaswinkler df6b991161 File permissions 2021-05-16 23:01:41 +02:00
Jonas Winkler 3f33f66387 New Crowdin updates (#1023) 2021-05-16 13:13:54 +02:00
jonaswinkler 870808f3c2 add support for configuring mail server character set per server. fixes #548 2021-05-16 11:58:32 +02:00
Jonas Winkler b12fcca20d Merge remote-tracking branch 'origin/dev' into dev 2021-05-16 01:23:07 +02:00
Jonas Winkler 61b47e358f correct file mode 2021-05-16 01:22:51 +02:00
Jonas Winkler 40a2fb7936 New Crowdin updates (#1022) 2021-05-15 21:14:03 +02:00
jonaswinkler 9afc8ba43d Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-05-15 19:21:34 +02:00
jonaswinkler b122a05c71 changelog and version bump 2021-05-15 19:21:15 +02:00
Jonas Winkler f568a9fdfa Merge pull request #934 from sbrunner/no-progress
Add --no-progress-bar option to commands
2021-05-15 19:06:50 +02:00
jonaswinkler a350bb3086 add translation hint 2021-05-15 18:58:23 +02:00
jonaswinkler 8ae4b7560b added some missing strings 2021-05-15 18:53:55 +02:00
jonaswinkler 96f4924911 frontend support for fulltext sorting 2021-05-15 18:48:39 +02:00
jonaswinkler f3703fc6e3 only show score when sorting by score 2021-05-15 17:25:49 +02:00
jonaswinkler 0d5fd229bf disable reverse sorting by score 2021-05-15 17:11:26 +02:00
jonaswinkler 1519e66550 fix pycodestyle 2021-05-15 15:14:22 +02:00
Jonas Winkler fcae461430 Merge pull request #1003 from puuu/baseurl
Fix sub path support
2021-05-15 15:12:00 +02:00
jonaswinkler 039d797dfc Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-05-15 15:00:39 +02:00
Jonas Winkler 4f61868b28 New Crowdin updates (#989) 2021-05-15 15:00:00 +02:00
jonaswinkler 9efbc55fd6 update dependencies 2021-05-15 14:59:35 +02:00
Jonas Winkler 2e4e88114e Merge pull request #1019 from amenk/feature/print-css-for-doc-list
Add print css for document list
2021-05-15 14:35:02 +02:00
jonaswinkler 8ee2e8b23d sorting for full text queries 2021-05-15 13:58:11 +02:00
Alexander Menk 37287c3e7e Add print css for document list
Allow printing of the document list in a clean way

* Hide sidebar, filter
* Use full width
2021-05-15 12:26:04 +02:00
jonaswinkler 814d90745b Workaround for all PDFminer.six issues. 2021-05-15 12:15:32 +02:00
jonaswinkler 48e8076e34 Merge branch 'master' into dev 2021-05-15 12:04:45 +02:00
Jonas Winkler edb9d934b2 Merge pull request #1017 from muued/patch-3
fix description of paperless-scheduler.service
2021-05-14 21:14:14 +02:00
Fabian Ohler ed44f0cb04 fix description of paperless-scheduler.service 2021-05-14 13:43:39 +02:00
puuu 1c2f3cf9af Fix serving static files under root_path 2021-05-14 18:14:59 +09:00
puuu 13afd25690 Update documentation about PAPERLESS_FORCE_SCRIPT_NAME 2021-05-14 15:39:20 +09:00
puuu f9b6374685 use {% url %} template to refere to root path 2021-05-14 14:44:13 +09:00
puuu 56c9b578e3 Make redirections respect root_path or STATIC_URL, name IndexView 2021-05-14 14:44:13 +09:00
puuu e792a00feb Introduce BASE_URL, make LOGIN_URL and STATIC_URL work with subpath 2021-05-14 14:44:13 +09:00
puuu c35c4eade9 Introduce ConfigurableWorker to make uvicorn respect FORCE_SCRIPT_NAME 2021-05-14 14:44:13 +09:00
puuu 5bf725546b use baseURI for websocket and api calls 2021-05-14 14:44:13 +09:00
puuu 6b6862705e make all links relative 2021-05-14 14:44:13 +09:00
jonaswinkler b89b51b121 Merge branch 'master' into dev 2021-05-09 16:22:21 +02:00
Jonas Winkler 1b31388232 Merge pull request #995 from cmer/prevent-robot-indexing
Tell web crawlers to not index Paperless
2021-05-07 22:30:49 +02:00
Jonas Winkler 8256e73f04 Merge pull request #994 from shamoon/fix/issue-985
Respect user dark mode setting on login page
2021-05-07 22:30:03 +02:00
Carl Mercier fc4e59ec00 Tell web crawlers to not index Paperless 2021-05-07 14:02:11 -04:00
Michael Shamoon 428e00ba23 Respect user dark mode setting on login page 2021-05-07 10:50:08 -07:00
Jonas Winkler 2ccbb08c3f Merge pull request #992 from muued/patch-2
Mention lacking support for ARM in ansible setup
2021-05-06 20:58:59 +02:00
Jonas Winkler eefc026a17 Merge pull request #991 from muued/patch-1
Use ansible-galaxy for ansible setup
2021-05-06 17:51:21 +02:00
Fabian Ohler d89022a280 Mention lacking support for ARM in ansible setup
Since the jbig2enc dependency is pulled from a repository that only provides i386 and amd64 packages, the installation will fail on arm hosts.
2021-05-06 14:15:12 +02:00
Fabian Ohler 93bd24c9d2 Update setup.rst
use ansible-galaxy to fetch the ansible scripts to have a role called paperless-ng instead of ansible
2021-05-06 14:08:49 +02:00
Jonas Winkler 197aec2945 New Crowdin updates (#988)
* New translations django.po (French)
[ci skip]

* New translations messages.xlf (French)
[ci skip]

* New translations django.po (Portuguese)
[ci skip]

* New translations messages.xlf (Portuguese)
[ci skip]
2021-05-05 22:36:22 +02:00
Jonas Winkler e16d58cff5 New Crowdin updates (#986) 2021-05-05 14:49:08 +02:00
Jonas Winkler 92667009be add swedish locale 2021-05-04 17:01:39 +02:00
Jonas Winkler c93657f40e New Crowdin updates (#976) 2021-05-04 15:28:10 +02:00
Jonas Winkler 16658f5939 Merge pull request #965 from jovandeginste/add-rtf
Add support for rtf
2021-04-30 19:11:07 +02:00
Jo Vandeginste ec0af59596 Add support for rtf
Signed-off-by: Jo Vandeginste <Jo.Vandeginste@kuleuven.be>
2021-04-30 13:19:12 +02:00
Jonas Winkler 9e1f9d6d9d Merge pull request #960 from shamoon/fix/issue-65-2
Remove PDF type attribute to fix macOS Safari native PDF viewer crashing
2021-04-28 16:45:22 +02:00
Michael Shamoon e652b927ce Remove type attribute of pdf object in document detail 2021-04-28 07:32:18 -07:00
Jonas Winkler 5a97f3f94b update libseccomp2 2021-04-28 02:12:55 +02:00
Jonas Winkler 9494c243a4 changelog, version bump 2021-04-27 22:52:50 +02:00
Jonas Winkler c0a1be4325 Merge pull request #956 from WhiteHatTux/bugfix/879
Use gosu as it is less complicated than sudo
2021-04-27 09:59:05 +02:00
Jonas Winkler 70fda8e2f8 New Crowdin updates (#932) 2021-04-27 09:52:30 +02:00
Christopher Timm 5765893f69 Use gosu instead of sudo for easier configuration
#879
2021-04-26 19:06:30 -05:00
Stéphane Brunner dc26c9b7cc Add --no-progress-bar option to commands 2021-04-18 16:16:11 +02:00
jonaswinkler 17b9d7eb42 Merge branch 'master' into dev 2021-04-18 12:41:52 +02:00
jonaswinkler 0a897cae32 bugfix 2021-04-18 11:29:12 +02:00
jonaswinkler 37f56e824a Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-04-18 11:25:21 +02:00
jonaswinkler a8e7ec0e96 changelog, version bump 2021-04-18 11:25:11 +02:00
Jonas Winkler b86d853cf1 New Crowdin updates (#931) 2021-04-18 10:49:22 +02:00
Jonas Winkler da0c94c9a1 New Crowdin updates (#930) 2021-04-17 22:33:42 +02:00
jonaswinkler 0547fd2760 fix minor issue 2021-04-17 22:33:06 +02:00
jonaswinkler e0a6df8435 Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-04-17 22:30:45 +02:00
jonaswinkler c2d4ca7566 lets hope this works 2021-04-17 22:29:54 +02:00
jonaswinkler 56ce278bbd update FAQ 2021-04-17 22:29:24 +02:00
Jonas Winkler e112541f5b New Crowdin updates (#929) 2021-04-17 20:34:57 +02:00
jonaswinkler 17c7b0840b changes for django 3.2 2021-04-17 16:00:29 +02:00
jonaswinkler 68658bd407 update dependencies 2021-04-17 14:56:25 +02:00
Jonas Winkler 9184845a9d Merge pull request #890 from what-name/feature/superuser-manager
Create initial Paperless user automatically
2021-04-17 14:44:01 +02:00
Jonas Winkler 8ddb2fb305 New Crowdin updates (#928) 2021-04-17 14:37:31 +02:00
jonaswinkler 96f53986b7 pycodestyle 2021-04-17 14:36:04 +02:00
jonaswinkler 8566682209 add test case, update password if changed 2021-04-17 14:33:07 +02:00
jonaswinkler 4f9ae17059 Merge branch 'dev' into feature/superuser-manager
# Conflicts:
#	docker/docker-entrypoint.sh
2021-04-17 14:10:56 +02:00
jonaswinkler 7f9f805c5f Merge branch 'dev' into feature/superuser-manager 2021-04-17 14:01:42 +02:00
Jonas Winkler 5208e81715 Merge pull request #856 from sbrl/patch-1
docker-entrypoint.sh: don't crash on chown errors
2021-04-17 13:57:14 +02:00
Jonas Winkler 01a786c117 Merge pull request #894 from lknop/master
add single compose file for usage in portainer environments
2021-04-17 13:50:11 +02:00
Jonas Winkler 8bf4f31954 Merge pull request #918 from shamoon/fix/issue-907
"Sticky" filter editor and bulk editor
2021-04-17 13:48:54 +02:00
jonaswinkler 07ab3e98ed add pl-PL locale 2021-04-17 13:41:26 +02:00
Jonas Winkler ba5899de7b New Crowdin updates (#874) 2021-04-17 13:34:42 +02:00
Michael Shamoon a4fef056ed Fix breakpoint
File missing from last commit
2021-04-14 13:24:03 -07:00
Michael Shamoon c266cd6aae Spacing tweaks, mobile breakpoint 2021-04-14 09:34:39 -07:00
Michael Shamoon 43d05b2e6d Hide visible underlying shadows on filter / bulk editor 2021-04-14 09:00:57 -07:00
Michael Shamoon 6f0c14cc07 Make filter editor / bulk editor 'sticky' on scroll 2021-04-14 09:00:30 -07:00
Lukasz Knop 2eac8fa91c disabled unnecessary overrides, copied variable comments 2021-04-11 21:48:50 +02:00
Lukasz Knop 31f5e178b3 add single compose file for usage in portainer environments 2021-04-11 15:16:04 +02:00
Chris Nagy c3d7088168 Fix code guidelines 2021-04-10 16:10:45 +02:00
Chris Nagy a9e11b1cb7 Add newline end of file 2021-04-10 16:02:48 +02:00
Chris Nagy ee51a0be13 Minor docs change 2021-04-10 15:08:33 +02:00
jonaswinkler 1091387f48 better logging for the retagger 2021-04-10 14:38:39 +02:00
jonaswinkler 4db75537cb install sudo from stable 2021-04-10 14:38:19 +02:00
Chris Nagy cb4e738a0f Fix env variable in docker entrypoint 2021-04-10 13:50:52 +02:00
Chris Nagy 0cc32e7ed7 Extend docs with superuser 2021-04-10 13:47:31 +02:00
Jonas Winkler 94f90e1e81 Merge pull request #887 from alexpovel/master
Fix typo
2021-04-10 00:21:45 +02:00
Alex Povel ce8f315747 Fix typo
See also https://github.com/jonaswinkler/paperless-ng/blob/a3c4e4c6b65086f9c1af9569b9a771ef8320d917/docker/compose/docker-compose.env#L30
2021-04-09 22:14:09 +02:00
Starbeamrainbowlabs b761a549c0 docker-prepare.sh: remove rogue instances of sudo
This is being done by calling the script as the correct user in the 
first place.
2021-04-08 03:06:01 +01:00
Starbeamrainbowlabs dd7c5da256 docker-entrypoint.sh: split non-root tasks into docker-prepare.sh 2021-04-08 00:03:55 +01:00
Starbeamrainbowlabs 02dd7ec615 docker: mark scripts as executable 2021-04-07 23:19:20 +01:00
Jonas Winkler b7b448b870 Merge pull request #875 from shamoon/fix/large-card-info-layout
Fix alignment of card info on large cards
2021-04-06 23:41:03 +02:00
Michael Shamoon b7326afe5a Fix alignment of card info on large cards 2021-04-06 14:25:59 -07:00
jonaswinkler a3c4e4c6b6 install script: configure time zone 2021-04-06 21:46:18 +02:00
jonaswinkler 645297d68c documentation 2021-04-06 21:46:16 +02:00
Jonas Winkler 6d8782f771 Merge pull request #860 from shamoon/feature/issue-858
Suppport search term PDF open parameter
2021-04-06 20:28:53 +02:00
Jonas Winkler 2728183eee New Crowdin updates (#871) 2021-04-06 20:23:18 +02:00
Michael Shamoon 3d0891c73b Updated to work with new unified search interface 2021-04-05 16:35:15 -07:00
Michael Shamoon 8226a8793e Merge remote-tracking branch 'upstream/dev' into feature/issue-858 2021-04-05 13:59:21 -07:00
jonaswinkler d01477b337 changelog 2021-04-05 22:23:11 +02:00
jonaswinkler 6bb07c72ab API search documentation 2021-04-05 22:19:42 +02:00
jonaswinkler a009462b80 update messages 2021-04-05 22:05:26 +02:00
jonaswinkler 9111b130e4 Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-04-05 21:53:39 +02:00
jonaswinkler 1dbd7b9bb4 fix some issues with the search index 2021-04-05 21:53:07 +02:00
Jonas Winkler 2f95dfc0e7 New Crowdin updates (#855) 2021-04-05 21:44:14 +02:00
Jonas Winkler acc317ddfd Merge pull request #818 from shamoon/fix/issue-817
Support passing current term from tag / document type / correspondent search field to 'create new' dialog
2021-04-05 21:43:50 +02:00
jonaswinkler 1fbd3935ea focus text filter input automatically 2021-04-05 21:43:20 +02:00
jonaswinkler ca2bf962e9 force update of search index if out of date 2021-04-05 21:33:17 +02:00
jonaswinkler 1d27a3a14b fixed the write permission check 2021-04-05 21:33:04 +02:00
jonaswinkler 8e1a9dde05 bugfix 2021-04-05 21:05:32 +02:00
Michael Shamoon 8eabf8c77a Refactor unneeded ngIf 2021-04-04 19:57:16 -07:00
Michael Shamoon ec4ec41552 Add back plus button which retains filter text 2021-04-04 17:05:27 -07:00
jonaswinkler 8960b0300f changelog and version bump 2021-04-05 00:36:44 +02:00
jonaswinkler d6a2672cab Merge branch 'feature-unified-search' into dev 2021-04-05 00:25:10 +02:00
jonaswinkler 4b281ca89d logging before executing pre and post consume scripts 2021-04-05 00:22:11 +02:00
jonaswinkler 808b507b0f fix migration 2021-04-05 00:16:50 +02:00
Michael Shamoon 18c028cafd Suppport search term PDF open parameter 2021-04-03 13:10:39 -07:00
Michael Shamoon 026c213ea4 Refactor to use ng-select addTag function 2021-04-03 09:30:29 -07:00
Michael Shamoon 9514e79bfb Not needed, clearing will be done by timeout 2021-03-24 12:42:14 -07:00
Michael Shamoon b6756595d9 Clear last search term when clear button clicked 2021-03-24 12:37:26 -07:00
Michael Shamoon 8ddb3e80b7 Add timeout for clearing last search term on select blur 2021-03-24 12:21:51 -07:00
Michael Shamoon 52bc1a62e1 Support passing current term from input-select search to create dialog e.g. for doc type / correspondent 2021-03-24 12:21:13 -07:00
Michael Shamoon cd72ed2cec Support passing current term from tag search to create dialog 2021-03-24 12:13:37 -07:00
Chris Nagy e3ba968fef Add superuser management script 2021-03-14 19:43:22 +01:00
194 changed files with 48565 additions and 8729 deletions

No files matched your search

+1 -1
View File
@@ -1 +1 @@
COMPOSE_PROJECT_NAME=paperless
COMPOSE_PROJECT_NAME=paperless
+37
View File
@@ -0,0 +1,37 @@
#!/bin/bash
# Verify that all text files end in a trailing newline.
# Exit on first failing command.
set -e
# Exit on unset variable.
set -u
success=0
function is_plaintext_file() {
local file="$1"
if [[ $file == *.svg ]]; then
echo ""
return
fi
file --brief "${file}" | grep text
}
# Split strings on newlines.
IFS='
'
for file in $(git ls-files)
do
if [[ -z $(is_plaintext_file "${file}") ]]; then
continue
fi
if ! [[ -z "$(tail -c 1 "${file}")" ]]; then
printf "File must end in a trailing newline: %s\n" "${file}" >&2
success=255
fi
done
exit "${success}"
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
# Check for trailing whitespace at end of lines.
# Exit on first failing command.
set -e
# Exit on unset variable.
set -u
FOUND_TRAILING_WHITESPACE=0
while read -r line; do
if grep \
"\s$" \
--line-number \
--with-filename \
--binary-files=without-match \
--exclude="*.svg" \
--exclude="*.eps" \
"${line}"; then
echo "ERROR: Found trailing whitespace" >&2;
FOUND_TRAILING_WHITESPACE=1
fi
done < <(git ls-files)
exit "${FOUND_TRAILING_WHITESPACE}"
+21 -7
View File
@@ -20,7 +20,7 @@ jobs:
name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.7
python-version: 3.9
-
name: Get pip cache dir
id: pip-cache
@@ -59,7 +59,7 @@ jobs:
name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.7
python-version: 3.9
-
name: Get pip cache dir
id: pip-cache
@@ -81,12 +81,26 @@ jobs:
run: |
cd src/
pycodestyle
whitespace:
runs-on: ubuntu-20.04
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Ensure there are no trailing spaces
run: |
.github/workflow-scripts/check-trailing-whitespace
-
name: Ensure all text files end with a trailing newline
run: |
.github/workflow-scripts/check-trailing-whitespace
tests:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: ['3.6', '3.7', '3.8', '3.9']
python-version: ['3.7', '3.8', '3.9']
fail-fast: false
steps:
-
@@ -122,7 +136,7 @@ jobs:
pytest
-
name: Publish coverage results
if: matrix.python-version == '3.8'
if: matrix.python-version == '3.9'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# https://github.com/coveralls-clients/coveralls-python/issues/251
@@ -158,7 +172,7 @@ jobs:
path: src/documents/static/frontend/
build-release:
needs: [frontend, documentation, tests, codestyle]
needs: [frontend, documentation, tests, whitespace, codestyle]
runs-on: ubuntu-20.04
steps:
-
@@ -168,7 +182,7 @@ jobs:
name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.7
python-version: 3.9
-
name: Install dependencies
run: |
@@ -268,7 +282,7 @@ jobs:
build-docker-image:
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/heads/feature-') || github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/ng-'))
runs-on: ubuntu-latest
needs: [frontend, tests, codestyle]
needs: [frontend, tests, whitespace, codestyle]
steps:
-
name: Prepare
+15 -15
View File
@@ -8,19 +8,18 @@ RUN git clone https://github.com/agl/jbig2enc .
RUN ./autogen.sh
RUN ./configure && make
FROM python:3.7-slim
FROM python:3.9-slim-bullseye
# Binary dependencies
RUN echo "deb http://deb.debian.org/debian bullseye main" > /etc/apt/sources.list.d/bullseye.list \
&& apt-get update \
&& apt-get -y --no-install-recommends install \
RUN apt-get update \
&& apt-get -y --no-install-recommends install \
# Basic dependencies
curl \
gnupg \
imagemagick \
gettext \
sudo \
tzdata \
gosu \
# fonts for text file thumbnail generation
fonts-liberation \
# for Numpy
@@ -28,16 +27,18 @@ RUN echo "deb http://deb.debian.org/debian bullseye main" > /etc/apt/sources.lis
libxslt1-dev \
# thumbnail size reduction
optipng \
# Mime type detection
libxml2 \
pngquant \
unpaper \
zlib1g \
ghostscript \
icc-profiles-free \
# Mime type detection
file \
libmagic-dev \
media-types \
# OCRmyPDF dependencies
ghostscript \
icc-profiles-free \
# OCRmyPDF dependencies
liblept5 \
libxml2 \
pngquant \
qpdf \
tesseract-ocr \
tesseract-ocr-eng \
@@ -45,8 +46,6 @@ RUN echo "deb http://deb.debian.org/debian bullseye main" > /etc/apt/sources.lis
tesseract-ocr-fra \
tesseract-ocr-ita \
tesseract-ocr-spa \
unpaper \
zlib1g \
&& rm -rf /var/lib/apt/lists/*
# copy jbig2enc
@@ -78,6 +77,7 @@ RUN cd docker \
&& mkdir /var/log/supervisord /var/run/supervisord \
&& cp supervisord.conf /etc/supervisord.conf \
&& cp docker-entrypoint.sh /sbin/docker-entrypoint.sh \
&& cp docker-prepare.sh /sbin/docker-prepare.sh \
&& chmod 755 /sbin/docker-entrypoint.sh \
&& chmod +x install_management_commands.sh \
&& ./install_management_commands.sh \
@@ -93,8 +93,8 @@ COPY src/ ./
RUN addgroup --gid 1000 paperless \
&& useradd --uid 1000 --gid paperless --home-dir /usr/src/paperless paperless \
&& chown -R paperless:paperless ../ \
&& sudo -HEu paperless python3 manage.py collectstatic --clear --no-input \
&& sudo -HEu paperless python3 manage.py compilemessages
&& gosu paperless python3 manage.py collectstatic --clear --no-input \
&& gosu paperless python3 manage.py compilemessages
VOLUME ["/usr/src/paperless/data", "/usr/src/paperless/media", "/usr/src/paperless/consume", "/usr/src/paperless/export"]
ENTRYPOINT ["/sbin/docker-entrypoint.sh"]
+8 -10
View File
@@ -10,19 +10,18 @@ name = "piwheels"
[packages]
dateparser = "~=1.0.0"
django = "~=3.1.3"
django = "~=3.2"
django-cors-headers = "*"
django-extensions = "*"
django-filter = "~=2.4.0"
django-q = "==1.3.4"
django-q = "~=1.3.4"
djangorestframework = "~=3.12.2"
filelock = "*"
fuzzywuzzy = {extras = ["speedup"], version = "*"}
gunicorn = "*"
imap-tools = "*"
langdetect = "*"
# numpy 1.20.0 drops python 3.6 support
numpy = "~=1.19.5"
numpy = "~=1.20.0"
pathvalidate = "*"
pillow = "~=8.1"
pikepdf = "~=2.5"
@@ -34,13 +33,11 @@ psycopg2-binary = "*"
redis = "*"
# Pinned because aarch64 wheels and updates cause warnings when loading the classifier model.
scikit-learn="==0.24.0"
# Prevent scipy updates because 1.6 is incompatible with python 3.6
scipy="~=1.5.4"
whitenoise = "~=5.2.0"
watchdog = "~=1.0.0"
whitenoise = "~=5.3.0"
watchdog = "~=2.1.0"
whoosh="~=2.7.4"
inotifyrecursive = "~=0.3.4"
ocrmypdf = "~=11.6"
ocrmypdf = "~=12.3"
tqdm = "*"
tika = "*"
# TODO: This will sadly also install daphne+dependencies,
@@ -50,9 +47,10 @@ channels-redis = "*"
uvicorn = {extras = ["standard"], version = "*"}
concurrent-log-handler = "*"
# uvloop 0.15+ incompatible with python 3.6
uvloop = "~=0.14.0"
uvloop = "~=0.15"
cryptography = "~=3.4"
"pdfminer.six" = "*"
"backports.zoneinfo" = "*"
[dev-packages]
coveralls = "*"
Generated
+766 -670
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -100,6 +100,7 @@ Paperless has been around a while now, and people are starting to build stuff on
* [Paperless App](https://github.com/bauerj/paperless_app): An Android/iOS app for Paperless. Updated to work with paperless-ng.
* [Paperless Share](https://github.com/qcasey/paperless_share). Share any files from your Android application with paperless. Very simple, but works with all of the mobile scanning apps out there that allow you to share scanned documents.
* [Scan to Paperless](https://github.com/sbrunner/scan-to-paperless): Scan and prepare (crop, deskew, OCR, ...) your documents for Paperless.
These projects also exist, but their status and compatibility with paperless-ng is unknown.
+10 -8
View File
@@ -12,27 +12,29 @@ Note that this role requires root access, so either run it in a playbook with a
- hosts: all
roles:
- role: ansible
- role: paperless-ng
become: yes
Role Variables
--------------
Most configuration variables from paperless-ng itself are available and accept their respective arguments.
Every `PAPERLESS_*` configuration varaible is lowercased and instead prefixed with `paperlessng_*` in `defaults/main.yml`.
Every `PAPERLESS_*` configuration variable is lowercased and instead prefixed with `paperlessng_*` in `defaults/main.yml`.
For a full listing including explainations and allowed values, see the current [documentation](https://paperless-ng.readthedocs.io/en/ng-0.9.14/configuration.html).
For a full listing including explanations and allowed values, see the current [documentation](https://paperless-ng.readthedocs.io/en/latest/configuration.html).
Additional variables available in this role are listed below, along with default values:
paperlessng_version: 0.9.14
paperlessng_version: latest
The [release](https://github.com/jonaswinkler/paperless-ng/releases) archive version of paperless-ng to install.
`latest` stands for the latest release of paperless-ng.
To install a specific version of paperless-ng, use the tag name of the release, e. g. `ng-1.4.4`, or specify a branch or commit id.
paperlessng_redis_host: localhost
paperlessng_redis_port: 6379
Seperate configuration values that combine into `PAPERLESS_REDIS`.
Separate configuration values that combine into `PAPERLESS_REDIS`.
paperlessng_db_type: sqlite
@@ -96,11 +98,11 @@ Example Playbook
- hosts: all
become: yes
vars_files:
- vars/main.yml
- vars/paperless-ng.yml
roles:
- ansible
- paperless-ng
`vars/main.yml`:
`vars/paperless-ng.yml`:
paperlessng_media_root: /mnt/media/smbshare
+1 -1
View File
@@ -1 +1 @@
COMPOSE_PROJECT_NAME=paperless
COMPOSE_PROJECT_NAME=paperless
@@ -0,0 +1,94 @@
# docker-compose file for running paperless from the Docker Hub.
# This file contains everything paperless needs to run.
# Paperless supports amd64, arm and arm64 hardware.
#
# All compose files of paperless configure paperless in the following way:
#
# - Paperless is (re)started on system boot, if it was running before shutdown.
# - Docker volumes for storing data are managed by Docker.
# - Folders for importing and exporting files are created in the same directory
# as this file and mounted to the correct folders inside the container.
# - Paperless listens on port 8010.
#
# In addition to that, this docker-compose file adds the following optional
# configurations:
#
# - Instead of SQLite (default), PostgreSQL is used as the database server.
#
# To install and update paperless with this file, do the following:
#
# - Open portainer Stacks list and click 'Add stack'
# - Paste the contents of this file and assign a name, e.g. 'Paperless'
# - Click 'Deploy the stack' and wait for it to be deployed
# - Open the list of containers, select paperless_webserver_1
# - Click 'Console' and then 'Connect' to open the command line inside the container
# - Run 'python3 manage.py createsuperuser' to create a user
# - Exit the console
#
# For more extensive installation and update instructions, refer to the
# documentation.
version: "3.4"
services:
broker:
image: redis:6.0
restart: unless-stopped
db:
image: postgres:13
restart: unless-stopped
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: paperless
webserver:
image: jonaswinkler/paperless-ng:latest
restart: unless-stopped
depends_on:
- db
- broker
ports:
- 8010:8000
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- data:/usr/src/paperless/data
- media:/usr/src/paperless/media
- ./export:/usr/src/paperless/export
- ./consume:/usr/src/paperless/consume
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
# The UID and GID of the user used to run paperless in the container. Set this
# to your UID and GID on the host so that you have write access to the
# consumption directory.
USERMAP_UID: 1000
USERMAP_GID: 100
# Additional languages to install for text recognition, separated by a
# whitespace. Note that this is
# different from PAPERLESS_OCR_LANGUAGE (default=eng), which defines the
# language used for OCR.
# The container installs English, German, Italian, Spanish and French by
# default.
# See https://packages.debian.org/search?keywords=tesseract-ocr-&searchon=names&suite=buster
# for available languages.
#PAPERLESS_OCR_LANGUAGES: tur ces
# Adjust this key if you plan to make paperless available publicly. It should
# be a very long sequence of random characters. You don't need to remember it.
#PAPERLESS_SECRET_KEY: change-me
# Use this variable to set a timezone for the Paperless Docker containers. If not specified, defaults to UTC.
#PAPERLESS_TIME_ZONE: America/Los_Angeles
# The default language to use for OCR. Set this to the language most of your
# documents are written in.
#PAPERLESS_OCR_LANGUAGE: eng
volumes:
data:
media:
pgdata:
@@ -75,10 +75,10 @@ services:
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg:
image: thecodingmachine/gotenberg
image: gotenberg/gotenberg:7
restart: unless-stopped
environment:
DISABLE_GOOGLE_CHROME: 1
CHROMIUM_DISABLE_ROUTES: 1
tika:
image: apache/tika
@@ -64,10 +64,10 @@ services:
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg:
image: thecodingmachine/gotenberg
image: gotenberg/gotenberg:7
restart: unless-stopped
environment:
DISABLE_GOOGLE_CHROME: 1
CHROMIUM_DISABLE_ROUTES: 1
tika:
image: apache/tika
Regular → Executable
+38 -91
View File
@@ -4,89 +4,37 @@ set -e
# Source: https://github.com/sameersbn/docker-gitlab/
map_uidgid() {
USERMAP_ORIG_UID=$(id -u paperless)
USERMAP_ORIG_GID=$(id -g paperless)
USERMAP_NEW_UID=${USERMAP_UID:-$USERMAP_ORIG_UID}
USERMAP_NEW_GID=${USERMAP_GID:-${USERMAP_ORIG_GID:-$USERMAP_NEW_UID}}
if [[ ${USERMAP_NEW_UID} != "${USERMAP_ORIG_UID}" || ${USERMAP_NEW_GID} != "${USERMAP_ORIG_GID}" ]]; then
echo "Mapping UID and GID for paperless:paperless to $USERMAP_NEW_UID:$USERMAP_NEW_GID"
usermod -u "${USERMAP_NEW_UID}" paperless
groupmod -o -g "${USERMAP_NEW_GID}" paperless
fi
}
wait_for_postgres() {
attempt_num=1
max_attempts=5
echo "Waiting for PostgreSQL to start..."
host="${PAPERLESS_DBHOST}"
port="${PAPERLESS_DBPORT}"
if [[ -z $port ]] ;
then
port="5432"
USERMAP_ORIG_UID=$(id -u paperless)
USERMAP_ORIG_GID=$(id -g paperless)
USERMAP_NEW_UID=${USERMAP_UID:-$USERMAP_ORIG_UID}
USERMAP_NEW_GID=${USERMAP_GID:-${USERMAP_ORIG_GID:-$USERMAP_NEW_UID}}
if [[ ${USERMAP_NEW_UID} != "${USERMAP_ORIG_UID}" || ${USERMAP_NEW_GID} != "${USERMAP_ORIG_GID}" ]]; then
echo "Mapping UID and GID for paperless:paperless to $USERMAP_NEW_UID:$USERMAP_NEW_GID"
usermod -u "${USERMAP_NEW_UID}" paperless
groupmod -o -g "${USERMAP_NEW_GID}" paperless
fi
while !</dev/tcp/$host/$port ;
do
if [ $attempt_num -eq $max_attempts ]
then
echo "Unable to connect to database."
exit 1
else
echo "Attempt $attempt_num failed! Trying again in 5 seconds..."
fi
attempt_num=$(expr "$attempt_num" + 1)
sleep 5
done
}
migrations() {
if [[ -n "${PAPERLESS_DBHOST}" ]]
then
wait_for_postgres
fi
(
# flock is in place to prevent multiple containers from doing migrations
# simultaneously. This also ensures that the db is ready when the command
# of the current container starts.
flock 200
echo "Apply database migrations..."
sudo -HEu paperless python3 manage.py migrate
) 200>/usr/src/paperless/data/migration_lock
}
initialize() {
map_uidgid
for dir in export data data/index media media/documents media/documents/originals media/documents/thumbnails; do
if [[ ! -d "../$dir" ]]
then
echo "creating directory ../$dir"
if [[ ! -d "../$dir" ]]; then
echo "Creating directory ../$dir"
mkdir ../$dir
fi
done
echo "creating directory /tmp/paperless"
echo "Creating directory /tmp/paperless"
mkdir -p /tmp/paperless
chown -R paperless:paperless ../
set +e
echo "Adjusting permissions of paperless files. This may take a while."
chown -R paperless:paperless /tmp/paperless
find .. -not \( -user paperless -and -group paperless \) -exec chown paperless:paperless {} +
set -e
migrations
gosu paperless /sbin/docker-prepare.sh
}
install_languages() {
@@ -102,44 +50,43 @@ install_languages() {
apt-get update
for lang in "${langs[@]}"; do
pkg="tesseract-ocr-$lang"
# English is installed by default
#if [[ "$lang" == "eng" ]]; then
# continue
#fi
pkg="tesseract-ocr-$lang"
# English is installed by default
#if [[ "$lang" == "eng" ]]; then
# continue
#fi
if dpkg -s $pkg &> /dev/null; then
echo "package $pkg already installed!"
continue
fi
if dpkg -s $pkg &>/dev/null; then
echo "Package $pkg already installed!"
continue
fi
if ! apt-cache show $pkg &> /dev/null; then
echo "package $pkg not found! :("
continue
fi
if ! apt-cache show $pkg &>/dev/null; then
echo "Package $pkg not found! :("
continue
fi
echo "Installing package $pkg..."
if ! apt-get -y install "$pkg" &> /dev/null; then
echo "Could not install $pkg"
exit 1
fi
done
echo "Installing package $pkg..."
if ! apt-get -y install "$pkg" &>/dev/null; then
echo "Could not install $pkg"
exit 1
fi
done
}
echo "Paperless-ng docker container starting..."
# Install additional languages if specified
if [[ ! -z "$PAPERLESS_OCR_LANGUAGES" ]]; then
install_languages "$PAPERLESS_OCR_LANGUAGES"
if [[ ! -z "$PAPERLESS_OCR_LANGUAGES" ]]; then
install_languages "$PAPERLESS_OCR_LANGUAGES"
fi
initialize
if [[ "$1" != "/"* ]]; then
echo Executing management command "$@"
exec sudo -HEu paperless python3 manage.py "$@"
exec gosu paperless python3 manage.py "$@"
else
echo Executing "$@"
exec "$@"
fi
+72
View File
@@ -0,0 +1,72 @@
#!/usr/bin/env bash
wait_for_postgres() {
attempt_num=1
max_attempts=5
echo "Waiting for PostgreSQL to start..."
host="${PAPERLESS_DBHOST}"
port="${PAPERLESS_DBPORT}"
if [[ -z $port ]]; then
port="5432"
fi
while ! </dev/tcp/$host/$port; do
if [ $attempt_num -eq $max_attempts ]; then
echo "Unable to connect to database."
exit 1
else
echo "Attempt $attempt_num failed! Trying again in 5 seconds..."
fi
attempt_num=$(expr "$attempt_num" + 1)
sleep 5
done
}
migrations() {
(
# flock is in place to prevent multiple containers from doing migrations
# simultaneously. This also ensures that the db is ready when the command
# of the current container starts.
flock 200
echo "Apply database migrations..."
python3 manage.py migrate
) 200>/usr/src/paperless/data/migration_lock
}
search_index() {
index_version=1
index_version_file=/usr/src/paperless/data/.index_version
if [[ (! -f "$index_version_file") || $(<$index_version_file) != "$index_version" ]]; then
echo "Search index out of date. Updating..."
python3 manage.py document_index reindex
echo $index_version | tee $index_version_file >/dev/null
fi
}
superuser() {
if [[ -n "${PAPERLESS_ADMIN_USER}" ]]; then
python3 manage.py manage_superuser
fi
}
do_work() {
if [[ -n "${PAPERLESS_DBHOST}" ]]; then
wait_for_postgres
fi
migrations
search_index
superuser
}
do_work
+1 -1
View File
@@ -1,4 +1,4 @@
for command in document_archiver document_exporter document_importer mail_fetcher document_create_classifier document_index document_renamer document_retagger document_thumbnails document_sanity_checker;
for command in document_archiver document_exporter document_importer mail_fetcher document_create_classifier document_index document_renamer document_retagger document_thumbnails document_sanity_checker manage_superuser;
do
echo "installing $command..."
sed "s/management_command/$command/g" management_script.sh > /usr/local/bin/$command
Regular → Executable
+1 -1
View File
@@ -6,7 +6,7 @@ cd /usr/src/paperless/src/
if [[ $(id -u) == 0 ]] ;
then
sudo -HEu paperless python3 manage.py management_command "$@"
gosu paperless python3 manage.py management_command "$@"
elif [[ $(id -un) == "paperless" ]] ;
then
python3 manage.py management_command "$@"
+9 -12
View File
@@ -149,22 +149,15 @@ Ansible Route
Most of the update process is automated when using the ansible role.
1. Backup your defined role variables file outside the paperless source-tree:
1. Update the role to the target release tag to make sure the ansible scripts are compatible:
.. code:: shell-session
$ cp ansible/vars.yml ~/vars.yml.old
$ ansible-galaxy install git+https://github.com/jonaswinkler/paperless-ng.git,master --force
2. Pull the release tag you want to update to:
2. Update the role variable definitions ``vars/paperless-ng.yml`` (where appropriate).
.. code:: shell-session
$ git fetch --all
$ git checkout ng-0.9.14
3. Update the role variable definitions ``ansible/vars.yml`` (where appropriate).
4. Run the ansible playbook you created created during :ref:`installation <setup-ansible>` again:
3. Run the ansible playbook you created created during :ref:`installation <setup-ansible>` again:
.. note::
@@ -193,7 +186,9 @@ This table lists the compatible versions for each database migration number.
+------------------+-----------------+
| 1012 | 1.1.0 - 1.2.1 |
+------------------+-----------------+
| 1014 | 1.3.0 - current |
| 1014 | 1.3.0 - 1.3.1 |
+------------------+-----------------+
| 1016 | 1.3.2 - current |
+------------------+-----------------+
Execute the following management command to migrate your database:
@@ -245,6 +240,8 @@ Document exporter
The document exporter exports all your data from paperless into a folder for
backup or migration to another DMS.
If you use the document exporter within a cronjob to backup your data you might use the ``-T`` flag behind exec to suppress "The input device is not a TTY" errors. For example: ``docker-compose exec -T webserver document_exporter ../export``
.. code::
document_exporter target [-c] [-f] [-d]
+38 -74
View File
@@ -147,93 +147,57 @@ The REST api provides three different forms of authentication.
Searching for documents
#######################
Paperless-ng offers API endpoints for full text search. These are as follows:
Full text searching is available on the ``/api/documents/`` endpoint. Two specific
query parameters cause the API to return full text search results:
``/api/search/``
================
* ``/api/documents/?query=your%20search%20query``: Search for a document using a full text query.
For details on the syntax, see :ref:`basic-usage_searching`.
Get search results based on a query.
* ``/api/documents/?more_like=1234``: Search for documents similar to the document with id 1234.
Query parameters:
Pagination works exactly the same as it does for normal requests on this endpoint.
* ``query``: The query string. See
`here <https://whoosh.readthedocs.io/en/latest/querylang.html>`_
for details on the syntax.
* ``page``: Specify the page you want to retrieve. Each page
contains 10 search results and the first page is ``page=1``, which
is the default if this is omitted.
Certain limitations apply to full text queries:
Result list object returned by the endpoint:
* Results are always sorted by search score. The results matching the query best will show up first.
.. code:: json
* Only a small subset of filtering parameters are supported.
Furthermore, each returned document has an additional ``__search_hit__`` attribute with various information
about the search results:
.. code::
{
"count": 1,
"page": 1,
"page_count": 1,
"corrected_query": "",
"count": 31,
"next": "http://localhost:8000/api/documents/?page=2&query=test",
"previous": null,
"results": [
...
{
"id": 123,
"title": "title",
"content": "content",
...
"__search_hit__": {
"score": 0.343,
"highlights": "text <span class=\"match\">Test</span> text",
"rank": 23
}
},
...
]
}
* ``count``: The approximate total number of results.
* ``page``: The page returned to you. This might be different from
the page you requested, if you requested a page that is behind
the last page. In that case, the last page is returned.
* ``page_count``: The total number of pages.
* ``corrected_query``: Corrected version of the query string. Can be null.
If not null, can be used verbatim to start a new query.
* ``results``: A list of result objects on the current page.
Result object:
.. code:: json
{
"id": 1,
"highlights": [
],
"score": 6.34234,
"rank": 23,
"document": {
}
}
* ``id``: the primary key of the found document
* ``highlights``: an object containing parsable highlights for the result.
See below.
* ``score``: The score assigned to the document. A higher score indicates a
better match with the query. Search results are sorted descending by score.
* ``rank``: the position of the document within the entire search results list.
* ``document``: The full json of the document, as returned by
``/api/documents/<id>/``.
Highlights object:
Highlights are provided as a list of fragments. A fragment is a longer section of
text from the original document.
Each fragment contains a list of strings, and some of them are marked as a highlight.
.. code:: json
[
[
{"text": "This is a sample text with a ", "highlight": false},
{"text": "highlighted", "highlight": true},
{"text": " word.", "highlight": false}
],
[
{"text": "Another", "highlight": true},
{"text": " fragment with a highlight.", "highlight": false}
]
]
A client may use this example to produce the following output:
... This is a sample text with a **highlighted** word. ... **Another** fragment with a highlight. ...
* ``score`` is an indication how well this document matches the query relative to the other search results.
* ``highlights`` is an excerpt from the document content and highlights the search terms with ``<span>`` tags as shown above.
* ``rank`` is the index of the search results. The first result will have rank 0.
``/api/search/autocomplete/``
=============================
+110 -11
View File
@@ -5,6 +5,110 @@
Changelog
*********
paperless-ng 1.5.0
##################
Support for Python 3.6 was dropped.
* Updated python dependencies.
* Base image of the docker image changed from Debian Buster to Debian Bullseye due to its recent release.
* The docker image now uses python 3.9.
* Added the Luxembourgish locale. Thanks for translating!
* `Daniel Albers`_ added support for making the files and folders ignored by the paperless consume folder scanner configurable. See ``PAPERLESS_CONSUMER_IGNORE_PATTERNS``.
paperless-ng 1.4.5
##################
This is a maintenance release.
* Updated Python and Angular dependencies.
* Changed the algorithm that changes permissions during startup. This is still fast,
and will hopefully cause less issues.
* Fixed an issue that would sometimes cause paperless to write an incomplete
classification model file to disk.
* Fixed an issue with the OCRmyPDF parser that would always try to extract text
with PDFminer even from non-PDF files.
paperless-ng 1.4.4
##################
* Drastically decreased the startup time of the docker container. The startup script adjusts file permissions of all data only if changes are required.
* Paperless mail: Added ability to specify the character set for each server.
* Document consumption: Ignore Mac OS specific files such as ``.DS_STORE`` and ``._XXXXX.pdf``.
* Fixed an issue with the automatic matching algorithm that prevents paperless from consuming new files.
* Updated translations.
paperless-ng 1.4.3
##################
* Additions and changes
* Added Swedish locale.
* `Stéphane Brunner`_ added an option to disable the progress bars of all management commands.
* `Jo Vandeginste`_ added support for RTF documents to the Apache TIKA parser.
* `Michael Shamoon`_ added dark mode for the login and logout pages.
* `Alexander Menk`_ added additional stylesheets for printing. You can now print any page of paperless and the print result will hide the page header, sidebar, and action buttons.
* Added support for sorting when using full text search.
* Fixes
* `puuu`_ fixed ``PAPERLESS_FORCE_SCRIPT_NAME``. You can now host paperless on sub paths such as ``https://localhost:8000/paperless/``.
* Fixed an issue with the document consumer crashing on certain documents due to issues with pdfminer.six. This library is used for PDF text extraction.
paperless-ng 1.4.2
##################
* Fixed an issue with ``sudo`` that caused paperless to not start on many Raspberry Pi devices. Thank you `WhiteHatTux`_!
paperless-ng 1.4.1
##################
* Added Polish locale.
* Changed some parts of the Dockerfile to hopefully restore functionality on certain ARM devices.
* Updated python dependencies.
* `Michael Shamoon`_ added a sticky filter / bulk edit bar.
* `sbrl`_ changed the docker-entrypoint.sh script to increase compatibility with NFS shares.
* `Chris Nagy`_ added support for creating a super user by passing ``PAPERLESS_ADMIN_USER`` and
``PAPERLESS_ADMIN_PASSWORD`` as environment variables to the docker container.
paperless-ng 1.4.0
##################
* Docker images now use tesseract 4.1.1, which should fix a series of issues with OCR.
* The full text search now displays results using the default document list. This enables
selection, filtering and bulk edit on search results.
* Changes
* Firefox only: Highlight search query in PDF previews.
* New URL pattern for accessing documents by ASN directly (http://<paperless>/asn/123)
* Added logging when executing pre- and post-consume scripts.
* Better error logging during document consumption.
* Updated python dependencies.
* Automatically inserts typed text when opening "Create new" dialogs on the document details page.
* Fixes
* Fixed an issue with null characters in the document content.
.. note::
The changed to the full text searching require you to reindex your documents.
*The docker image does this automatically, you don't need to do anything.*
To do this, execute the ``document_index reindex`` management command
(see :ref:`administration-index`).
paperless-ng 1.3.2
##################
@@ -108,17 +212,6 @@ paperless-ng 1.2.0
* Paperless no longer depends on ``libpoppler-cpp-dev``.
.. note::
Some packages that paperless depends on are slowly dropping Python 3.6
support one after another, including the web server. Supporting Python
3.6 means that I cannot update these packages anymore.
At some point, paperless will drop Python 3.6 support. If using a bare
metal installation and you're still on Python 3.6, upgrade to 3.7 or newer.
If using docker, this does not affect you.
paperless-ng 1.1.4
##################
@@ -1312,6 +1405,11 @@ bulk of the work on this big change.
* Initial release
.. _Alexander Menk: https://github.com/amenk
.. _puuu: https://github.com/puuu
.. _WhiteHatTux: https://github.com/WhiteHatTux
.. _Chris Nagy: https://github.com/what-name
.. _sbrl: https://github.com/sbrl
.. _slorenz: https://github.com/sisao
.. _Jo Vandeginste: https://github.com/jovandeginste
.. _zjean: https://github.com/zjean
@@ -1384,6 +1482,7 @@ bulk of the work on this big change.
.. _JOKer: https://github.com/MasterofJOKers
.. _Brian Cribbs: https://github.com/cribbstechnolog
.. _Brendan M. Sleight: https://github.com/bmsleight
.. _Daniel Albers: https://github.com/AlD
.. _#20: https://github.com/the-paperless-project/paperless/issues/20
.. _#44: https://github.com/the-paperless-project/paperless/issues/44
+49 -13
View File
@@ -154,10 +154,6 @@ PAPERLESS_FORCE_SCRIPT_NAME=<path>
To host paperless under a subpath url like example.com/paperless you set
this value to /paperless. No trailing slash!
.. note::
I don't know if this works in paperless-ng. Probably not.
Defaults to none, which hosts paperless at "/".
PAPERLESS_STATIC_URL=<path>
@@ -177,6 +173,30 @@ PAPERLESS_AUTO_LOGIN_USERNAME=<username>
Defaults to none, which disables this feature.
PAPERLESS_ADMIN_USER=<username>
If this environment variable is specified, Paperless automatically creates
a superuser with the provided username at start. This is useful in cases
where you can not run the `createsuperuser` command seperately, such as Kubernetes
or AWS ECS.
Requires `PAPERLESS_ADMIN_PASSWORD` to be set.
.. note::
This will not change an existing [super]user's password, nor will
it recreate a user that already exists. You can leave this throughout
the lifecycle of the containers.
PAPERLESS_ADMIN_MAIL=<email>
(Optional) Specify superuser email address. Only used when
`PAPERLESS_ADMIN_USER` is set.
Defaults to ``root@localhost``.
PAPERLESS_ADMIN_PASSWORD=<password>
Only used when `PAPERLESS_ADMIN_USER` is set.
This will be the password of the automatically created superuser.
PAPERLESS_COOKIE_PREFIX=<str>
Specify a prefix that is added to the cookies used by paperless to identify
@@ -202,17 +222,17 @@ PAPERLESS_ENABLE_HTTP_REMOTE_USER=<bool>
Also see the warning `in the official documentation <https://docs.djangoproject.com/en/3.1/howto/auth-remote-user/#configuration>`.
Defaults to `false` which disables this feature.
PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME=<str>
If `PAPERLESS_ENABLE_HTTP_REMOTE_USER` is enabled, this property allows to
customize the name of the HTTP header from which the authenticated username
If `PAPERLESS_ENABLE_HTTP_REMOTE_USER` is enabled, this property allows to
customize the name of the HTTP header from which the authenticated username
is extracted. Values are in terms of
[HttpRequest.META](https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.HttpRequest.META).
Thus, the configured value must start with `HTTP_` followed by the
Thus, the configured value must start with `HTTP_` followed by the
normalized actual header name.
Defaults to `HTTP_REMOTE_USER`.
.. _configuration-ocr:
OCR settings
@@ -238,6 +258,8 @@ PAPERLESS_OCR_LANGUAGE=<lang>
Defaults to "eng".
Note: If your language contains a '-' such as chi-sim, you must use chi_sim
PAPERLESS_OCR_MODE=<mode>
Tell paperless when and how to perform ocr on your documents. Four modes
are available:
@@ -380,7 +402,7 @@ Tika settings
#############
Paperless can make use of `Tika <https://tika.apache.org/>`_ and
`Gotenberg <https://thecodingmachine.github.io/gotenberg/>`_ for parsing and
`Gotenberg <https://gotenberg.dev/>`_ for parsing and
converting "Office" documents (such as ".doc", ".xlsx" and ".odt"). If you
wish to use this, you must provide a Tika server and a Gotenberg server,
configure their endpoints, and enable the feature.
@@ -422,10 +444,10 @@ requires are as follows:
# ...
gotenberg:
image: thecodingmachine/gotenberg
image: gotenberg/gotenberg:7
restart: unless-stopped
environment:
DISABLE_GOOGLE_CHROME: 1
CHROMIUM_DISABLE_ROUTES: 1
tika:
image: apache/tika
@@ -602,6 +624,20 @@ PAPERLESS_IGNORE_DATES=<string>
Defaults to an empty string to not ignore any dates.
PAPERLESS_DATE_ORDER=<format>
Paperless will try to determine the document creation date from its contents.
Specify the date format Paperless should expect to see within your documents.
This option defaults to DMY which translates to day first, month second, and year
last order. Characters D, M, or Y can be shuffled to meet the required order.
PAPERLESS_CONSUMER_IGNORE_PATTERNS=<json>
By default, paperless ignores certain files and folders in the consumption
directory, such as system files created by the Mac OS.
This can be adjusted by configuring a custom json array with patterns to exclude.
Defautls to ``[".DS_STORE/*", "._*", ".stfolder/*"]``.
Binaries
########
+1 -1
View File
@@ -6,7 +6,7 @@ Contributing to Paperless
.. warning::
This section is not updated to paperless-ng yet.
Maybe you've been using Paperless for a while and want to add a feature or two,
or maybe you've come across a bug that you have some ideas how to solve. The
beauty of Free software is that you can see what's wrong and help to get it
+9 -9
View File
@@ -23,10 +23,10 @@ Apart from that, the folder structure is as follows:
* ``scripts/`` - Various scripts that help with different parts of development.
* ``docker/`` - Files required to build the docker image.
Initial setup and first start
Initial setup and first start
=============================
After you forked and cloned the code from github you need to perform a first-time setup.
After you forked and cloned the code from github you need to perform a first-time setup.
To do the setup you need to perform the steps from the following chapters in a certain order:
1. Install prerequisites + pipenv as mentioned in :ref:`Bare metal route <setup-bare_metal>`
@@ -35,19 +35,19 @@ To do the setup you need to perform the steps from the following chapters in a c
.. code:: shell-session
$ npm install -g @angular/cli
$ npm install -g @angular/cli
4. Create ``consume`` and ``media`` folders in the cloned root folder.
.. code:: shell-session
mkdir -p consume media
5. You can now either ...
* install redis or
* install redis or
* use the included scripts/start-services.sh to use docker to fire up a redis instance (and some other services such as tika, gotenberg and a postgresql server) or
* spin up a bare redis container
* spin up a bare redis container
.. code:: shell-session
@@ -79,7 +79,7 @@ To do the setup you need to perform the steps from the following chapters in a c
python3 manage.py runserver & python3 manage.py document_consumer & python3 manage.py qcluster
10. Login with the superuser credentials provided in step 8 at ``http://localhost:8000`` to create a session that enables you to use the backend.
Backend development environment is now ready, to start Frontend development go to ``/src-ui`` and run ``ng serve``. From there you can use ``http://localhost:4200`` for a preview.
Back end development
@@ -207,7 +207,7 @@ Adding new languages requires adding the translated files in the "src-ui/src/loc
// Add your new language here
]
}
``dateInputFormat`` is a special string that defines the behavior of the date input fields and absolutely needs to contain "dd", "mm" and "yyyy".
3. Import and register the Angular data for this locale in "src-ui/src/app/app.module.ts":
@@ -320,7 +320,7 @@ methods ``parse`` and ``get_thumbnail``. You can provide your own implementation
# The content of the document.
self.text = "content"
# Optional: path to a PDF document that you created from the original.
self.archive_path = os.path.join(self.tempdir, "archived.pdf")
+2 -2
View File
@@ -68,10 +68,10 @@ reuse the text. The web interface is a lot snappier, since it runs
in your browser and paperless has to do much less work to serve the data.
.. note::
You can adjust some of the settings so that paperless uses less processing
power. See :ref:`setup-less_powerful_devices` for details.
**Q:** *How do I install paperless-ng on Raspberry Pi?*
+1 -1
View File
@@ -49,7 +49,7 @@ resources in the documentation:
paperless-ng.
* Paperless is now integrated with a
:ref:`task processing queue <setup-task_processor>` that tells you
at a glance when and why something is not working.
at a glance when and why something is not working.
* The :ref:`changelog <paperless_changelog>` contains a detailed list of all changes
in paperless-ng.
+35 -25
View File
@@ -13,42 +13,48 @@ that works right for you based on recommendations from other Paperless users.
Physical scanners
=================
+---------+----------------+-----+-----+-----+------+----------------+
| Brand | Model | Supports | Recommended By |
+---------+----------------+-----+-----+-----+------+----------------+
| | | FTP | NFS | SMB | SMTP | |
+=========+================+=====+=====+=====+======+================+
| Brother | `ADS-1700W`_ | yes | no | yes | yes |`holzhannes`_ |
+---------+----------------+-----+-----+-----+------+----------------+
| Brother | `ADS-1600W`_ | yes | no | yes | yes |`holzhannes`_ |
+---------+----------------+-----+-----+-----+------+----------------+
| Brother | `ADS-1500W`_ | yes | no | yes | yes |`danielquinn`_ |
+---------+----------------+-----+-----+-----+------+----------------+
| Brother | `MFC-J6930DW`_ | yes | | | |`ayounggun`_ |
+---------+----------------+-----+-----+-----+------+----------------+
| Brother | `MFC-L5850DW`_ | yes | | | yes |`holzhannes`_ |
+---------+----------------+-----+-----+-----+------+----------------+
| Brother | `MFC-J5910DW`_ | yes | | | |`bmsleight`_ |
+---------+----------------+-----+-----+-----+------+----------------+
| Brother | `MFC-9142CDN`_ | yes | | yes | |`REOLDEV`_ |
+---------+----------------+-----+-----+-----+------+----------------+
| Fujitsu | `ix500`_ | yes | | yes | |`eonist`_ |
+---------+----------------+-----+-----+-----+------+----------------+
| Epson | `WF-7710DWF`_ | yes | | yes | |`Skylinar`_ |
+---------+----------------+-----+-----+-----+------+----------------+
| Fujitsu | `S1300i`_ | yes | | yes | |`jonaswinkler`_ |
+---------+----------------+-----+-----+-----+------+----------------+
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Brand | Model | Supports | Recommended By |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| | | FTP | NFS | SMB | SMTP | API [1]_ | |
+=========+================+=====+=====+=====+======+==========+================+
| Brother | `ADS-1700W`_ | yes | no | yes | yes | |`holzhannes`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Brother | `ADS-1600W`_ | yes | no | yes | yes | |`holzhannes`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Brother | `ADS-1500W`_ | yes | no | yes | yes | |`danielquinn`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Brother | `ADS-1100W`_ | yes | no | no | no | |`ytzelf`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Brother | `MFC-J6930DW`_ | yes | | | | |`ayounggun`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Brother | `MFC-L5850DW`_ | yes | | | yes | |`holzhannes`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Brother | `MFC-J5910DW`_ | yes | | | | |`bmsleight`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Brother | `MFC-9142CDN`_ | yes | | yes | | |`REOLDEV`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Fujitsu | `ix500`_ | yes | | yes | | |`eonist`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Epson | `WF-7710DWF`_ | yes | | yes | | |`Skylinar`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Fujitsu | `S1300i`_ | yes | | yes | | |`jonaswinkler`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
| Doxie | `Q2`_ | no | no | no | no | yes |`Unkn0wnCat`_ |
+---------+----------------+-----+-----+-----+------+----------+----------------+
.. _MFC-L5850DW: https://www.brother-usa.com/products/mfcl5850dw
.. _ADS-1700W: https://www.brother-usa.com/products/ads1700w
.. _ADS-1600W: https://www.brother-usa.com/products/ads1600w
.. _ADS-1500W: https://www.brother.ca/en/p/ads1500w
.. _ADS-1100W: https://support.brother.com/g/b/downloadtop.aspx?c=fr&lang=fr&prod=ads1100w_eu_as_cn
.. _MFC-J6930DW: https://www.brother.ca/en/p/MFCJ6930DW
.. _MFC-J5910DW: https://www.brother.co.uk/printers/inkjet-printers/mfcj5910dw
.. _MFC-9142CDN: https://www.brother.co.uk/printers/laser-printers/mfc9140cdn
.. _ix500: http://www.fujitsu.com/us/products/computing/peripheral/scanners/scansnap/ix500/
.. _WF-7710DWF: https://www.epson.de/en/products/printers/inkjet-printers/for-home/workforce-wf-7710dwf
.. _S1300i: https://www.fujitsu.com/global/products/computing/peripheral/scanners/soho/s1300i/
.. _Q2: https://www.getdoxie.com/product/doxie-q/
.. _danielquinn: https://github.com/danielquinn
@@ -59,6 +65,10 @@ Physical scanners
.. _Skylinar: https://github.com/Skylinar
.. _jonaswinkler: https://github.com/jonaswinkler
.. _holzhannes: https://github.com/holzhannes
.. _ytzelf: https://github.com/ytzelf
.. _Unkn0wnCat: https://github.com/Unkn0wnCat
.. [1] Scanners with API Integration allow to push scanned documents directly to :ref:`Paperless API <api-file_uploads>`, sometimes referred to as Webhook or Document POST.
Mobile phone software
=====================
+19 -23
View File
@@ -116,9 +116,7 @@ performs all the steps described in :ref:`setup-docker_hub` automatically.
.. code:: shell-session
$ wget https://raw.githubusercontent.com/jonaswinkler/paperless-ng/master/install-paperless-ng.sh
$ chmod +x install-paperless-ng.sh
$ ./install-paperless-ng.sh
$ curl -L https://raw.githubusercontent.com/jonaswinkler/paperless-ng/master/install-paperless-ng.sh | bash
.. _setup-docker_hub:
@@ -286,7 +284,7 @@ writing. Windows is not and will never be supported.
Use this list for your preferred package management:
.. code::
.. code::
python3 python3-pip python3-dev imagemagick fonts-liberation optipng gnupg libpq-dev libmagic-dev mime-support
@@ -305,7 +303,7 @@ writing. Windows is not and will never be supported.
Use this list for your preferred package management:
.. code::
.. code::
unpaper ghostscript icc-profiles-free qpdf liblept5 libxml2 pngquant zlib1g tesseract-ocr
@@ -360,7 +358,11 @@ writing. Windows is not and will never be supported.
Adjust as necessary if you configured different folders.
8. Install python requirements from the ``requirements.txt`` file.
It is up to you if you wish to use a virtual environment or not.
It is up to you if you wish to use a virtual environment or not. First you should update your pip, so it gets the actual packages.
.. code:: shell-session
sudo -Hu paperless pip3 install --upgrade pip
.. code:: shell-session
@@ -460,6 +462,7 @@ Install Paperless using ansible
.. note::
This role currently only supports Debian 10 Buster and Ubuntu 20.04 Focal or later as target hosts.
Additionally, only i386 or amd64 based hosts are supported right now, i.e. installation on arm hosts will fail.
1. Install ansible 2.7+ on the management node.
This may be the target host paperless-ng is being installed on or any remote host which can access the target host.
@@ -485,29 +488,22 @@ Install Paperless using ansible
ansible -m ping YourAnsibleTargetHostGoesHere
2. Clone the repository of paperless-ng:
2. Install the latest tag of the ansible role using ansible-galaxy
.. code:: sh
git clone https://github.com/jonaswinkler/paperless-ng
ansible-galaxy install git+https://github.com/jonaswinkler/paperless-ng.git,ng-1.4.2
Checkout the latest release tag:
.. code:: sh
cd paperless-ng
git checkout ng-1.0.0
3. Create an ansible ``playbook.yml`` in the paperless-ng root directory:
3. Create an ansible ``playbook.yml`` in a directory of your choice:
.. code:: yaml
- hosts: YourAnsibleTargetHostGoesHere
become: yes
vars_files:
- ansible/vars.yml
- vars/paperless-ng.yml
roles:
- ansible
- paperless-ng
Optional: If you also want to use PostgreSQL on the target system, install and add (for example) the `geerlingguy.postgresql <https://github.com/geerlingguy/ansible-role-postgresql>`_ role:
@@ -520,10 +516,10 @@ Install Paperless using ansible
- hosts: YourAnsibleTargetHostGoesHere
become: yes
vars_files:
- ansible/vars.yml
- vars/paperless-ng.yml
roles:
- geerlingguy.postgresql
- ansible
- paperless-ng
Optional: If you also want to use a reverse proxy on the target system, install and add (for example) the `geerlingguy.nginx <https://github.com/geerlingguy/ansible-role-nginx>`_ role:
@@ -536,13 +532,13 @@ Install Paperless using ansible
- hosts: YourAnsibleTargetHostGoesHere
become: yes
vars_files:
- ansible/vars.yml
- vars/paperless-ng.yml
roles:
- geerlingguy.postgresql
- ansible
- paperless-ng
- geerlingguy.nginx
4. Create ``ansible/vars.yml`` to configure your ansible deployment:
4. Create ``vars/paperless-ng.yml`` to configure your ansible deployment:
.. code:: yaml
+22 -9
View File
@@ -81,7 +81,7 @@ UserWarning in sklearn on every single document
You may encounter warnings like this:
.. code::
/usr/local/lib/python3.7/site-packages/sklearn/base.py:315:
UserWarning: Trying to unpickle estimator CountVectorizer from version 0.23.2 when using version 0.24.0.
This might lead to breaking code or invalid results. Use at your own risk.
@@ -101,22 +101,22 @@ You may experience these errors when using the optional TIKA integration:
.. code::
requests.exceptions.HTTPError: 504 Server Error: Gateway Timeout for url: http://gotenberg:3000/convert/office
requests.exceptions.HTTPError: 504 Server Error: Gateway Timeout for url: http://gotenberg:3000/forms/libreoffice/convert
Gotenberg is a server that converts Office documents into PDF documents and has a default timeout of 10 seconds.
Gotenberg is a server that converts Office documents into PDF documents and has a default timeout of 30 seconds.
When conversion takes longer, Gotenberg raises this error.
You can increase the timeout by configuring an environment variable for gotenberg (see also `here <https://thecodingmachine.github.io/gotenberg/#environment_variables.default_wait_timeout>`__).
You can increase the timeout by configuring an environment variable for Gotenberg (see also `here <https://gotenberg.dev/docs/modules/api#properties>`__).
If using docker-compose, this is achieved by the following configuration change in the ``docker-compose.yml`` file:
.. code:: yaml
gotenberg:
image: thecodingmachine/gotenberg
image: gotenberg/gotenberg:7
restart: unless-stopped
environment:
DISABLE_GOOGLE_CHROME: 1
DEFAULT_WAIT_TIMEOUT: 30
CHROMIUM_DISABLE_ROUTES: 1
API_PROCESS_TIMEOUT: 60
Permission denied errors in the consumption directory
#####################################################
@@ -200,11 +200,24 @@ This might have multiple reasons.
File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 386, in sendfile
sent += os.sendfile(sockno, fileno, offset + sent, count)
OSError: [Errno 22] Invalid argument
To fix this issue, add
.. code::
SENDFILE=0
to your `docker-compose.env` file.
Error while reading metadata
############################
You might find messages like these in your log files:
.. code::
[WARNING] [paperless.parsing.tesseract] Error while reading metadata
This indicates that paperless failed to read PDF metadata from one of your documents. This happens when you
open the affected documents in paperless for editing. Paperless will continue to work, and will simply not
show the invalid metadata.
+7 -5
View File
@@ -71,7 +71,7 @@ your documents:
This process can be configured to fit your needs. If you don't want paperless
to create archived versions for digital documents, you can configure that by
configuring ``PAPERLESS_OCR_MODE=skip_noarchive``. Please read the
configuring ``PAPERLESS_OCR_MODE=skip_noarchive``. Please read the
:ref:`relevant section in the documentation <configuration-ocr>`.
.. note::
@@ -255,6 +255,8 @@ Here are a couple examples of tags and types that you could use in your collecti
* A tag ``missing_metadata`` when you still need to add some metadata to a document, but can't
or don't want to do this right now.
.. _basic-usage_searching:
Searching
#########
@@ -287,7 +289,7 @@ Matching specific tags, correspondents or types:
Matching dates:
.. code::
created:[2005 to 2009]
added:yesterday
modified:today
@@ -304,11 +306,11 @@ Matching inexact words:
auto complete and query correction.
All of these constructs can be combined as you see fit.
If you want to learn more about the query language used by paperless, paperless uses Whoosh's default query language.
If you want to learn more about the query language used by paperless, paperless uses Whoosh's default query language.
Head over to `Whoosh query language <https://whoosh.readthedocs.io/en/latest/querylang.html>`_.
For details on what date parsing utilities are available, see
`Date parsing <https://whoosh.readthedocs.io/en/latest/dates.html#parsing-date-queries>`_.
.. _usage-recommended_workflow:
@@ -383,7 +385,7 @@ Once you have scanned in a document, proceed in paperless as follows.
6. Remove inbox tags from the documents.
.. hint::
You can setup manual matching rules for your correspondents and tags and
paperless will assign them automatically. After consuming a couple documents,
you can even ask paperless to *learn* when to assign tags and correspondents
+1 -1
View File
@@ -2,7 +2,7 @@ import os
bind = '0.0.0.0:8000'
workers = int(os.getenv("PAPERLESS_WEBSERVER_WORKERS", 2))
worker_class = 'uvicorn.workers.UvicornWorker'
worker_class = 'paperless.workers.ConfigurableWorker'
timeout = 120
def pre_fork(server, worker):
+13 -1
View File
@@ -62,7 +62,7 @@ if [[ -z $(which docker-compose) ]] ; then
exit 1
fi
# Check if user has permissions to run Docker by trying to get the status of Docker (docker status).
# Check if user has permissions to run Docker by trying to get the status of Docker (docker status).
# If this fails, the user probably does not have permissions for Docker.
docker stats --no-stream 2>/dev/null 1>&2
if [ $? -ne 0 ] ; then
@@ -73,6 +73,8 @@ if [ $? -ne 0 ] ; then
sleep 3
fi
default_time_zone=$(timedatectl show -p Timezone --value)
set -e
echo ""
@@ -145,6 +147,15 @@ echo ""
ask "Port" "8000"
PORT=$ask_result
echo ""
echo "Paperless requires you to configure the current time zone correctly."
echo "Otherwise, the dates of your documents may appear off by one day,"
echo "depending on where you are on earth."
echo ""
ask "Current time zone" "$default_time_zone"
TIME_ZONE=$ask_result
echo ""
echo "Database backend: PostgreSQL and SQLite are available. Use PostgreSQL"
echo "if unsure. If you're running on a low-power device such as Raspberry"
@@ -280,6 +291,7 @@ DEFAULT_LANGUAGES="deu eng fra ita spa"
if [[ ! $USERMAP_GID == "1000" ]] ; then
echo "USERMAP_GID=$USERMAP_GID"
fi
echo "PAPERLESS_TIME_ZONE=$TIME_ZONE"
echo "PAPERLESS_OCR_LANGUAGE=$OCR_LANGUAGE"
echo "PAPERLESS_SECRET_KEY=$SECRET_KEY"
if [[ ! " ${DEFAULT_LANGUAGES[@]} " =~ " ${OCR_LANGUAGE} " ]] ; then
+1
View File
@@ -57,6 +57,7 @@
#PAPERLESS_CONSUMER_POLLING=10
#PAPERLESS_CONSUMER_DELETE_DUPLICATES=false
#PAPERLESS_CONSUMER_RECURSIVE=false
#PAPERLESS_CONSUMER_IGNORE_PATTERNS=[".DS_STORE/*", "._*", ".stfolder/*"]
#PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS=false
#PAPERLESS_OPTIMIZE_THUMBNAILS=true
#PAPERLESS_POST_CONSUME_SCRIPT=/path/to/an/arbitrary/script.sh
+51 -48
View File
@@ -8,93 +8,96 @@
-i https://pypi.python.org/simple
--extra-index-url https://www.piwheels.org/simple
aioredis==1.3.1
arrow==1.0.3; python_version >= '3.6'
asgiref==3.3.1; python_version >= '3.5'
arrow==1.1.1; python_version >= '3.6'
asgiref==3.4.1; python_version >= '3.6'
async-timeout==3.0.1; python_full_version >= '3.5.3'
attrs==20.3.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
attrs==21.2.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
autobahn==21.3.1; python_version >= '3.7'
automat==20.2.0
blessed==1.18.0
certifi==2020.12.5
cffi==1.14.5
channels-redis==3.2.0
channels==3.0.3
backports.zoneinfo==0.2.1
blessed==1.18.1; python_version >= '2.7'
certifi==2021.5.30
cffi==1.14.6
channels-redis==3.3.0
channels==3.0.4
chardet==4.0.0; python_version >= '3.1'
click==7.1.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
coloredlogs==15.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
charset-normalizer==2.0.4; python_version >= '3'
click==8.0.1; python_version >= '3.6'
coloredlogs==15.0.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
concurrent-log-handler==0.9.19
constantly==15.1.0
cryptography==3.4.7
daphne==3.0.1; python_version >= '3.6'
daphne==3.0.2; python_version >= '3.6'
dateparser==1.0.0
django-cors-headers==3.7.0
django-extensions==3.1.1
django-cors-headers==3.8.0
django-extensions==3.1.3
django-filter==2.4.0
django-picklefield==3.0.1; python_version >= '3'
django-q==1.3.4
django==3.1.7
django-q==1.3.9
django==3.2.6
djangorestframework==3.12.4
filelock==3.0.12
fuzzywuzzy[speedup]==0.18.0
gunicorn==20.1.0
h11==0.12.0; python_version >= '3.6'
hiredis==2.0.0; python_version >= '3.6'
httptools==0.1.1
humanfriendly==9.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
httptools==0.2.0
humanfriendly==9.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
hyperlink==21.0.0
idna==2.10; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
imap-tools==0.39.0
img2pdf==0.4.0
idna==3.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
imap-tools==0.46.0
img2pdf==0.4.1
incremental==21.3.0
inotify-simple==1.3.5; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
inotifyrecursive==0.3.5
joblib==1.0.1; python_version >= '3.6'
langdetect==1.0.8
langdetect==1.0.9
lxml==4.6.3; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
msgpack==1.0.2
numpy==1.19.5
ocrmypdf==11.7.3
pathvalidate==2.4.0
numpy==1.20.3
ocrmypdf==12.3.2
pathvalidate==2.4.1
pdfminer.six==20201018
pikepdf==2.10.0
pillow==8.2.0
pikepdf==2.16.1
pillow==8.3.1
pluggy==0.13.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
portalocker==2.3.0; python_version >= '3'
psycopg2-binary==2.8.6
psycopg2-binary==2.9.1
pyasn1-modules==0.2.8
pyasn1==0.4.8
pycparser==2.20; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
pyopenssl==20.0.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
python-dateutil==2.8.1
python-dotenv==0.16.0
python-dateutil==2.8.2
python-dotenv==0.19.0
python-gnupg==0.4.7
python-levenshtein==0.12.2
python-magic==0.4.22
python-magic==0.4.24
pytz==2021.1
pyyaml==5.4.1
redis==3.5.3
regex==2021.3.17
reportlab==3.5.66; python_version >= '2.7' and python_version < '4'
requests==2.25.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
regex==2021.8.3
reportlab==3.6.1; python_version >= '2.7' and python_version < '4'
requests==2.26.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'
scikit-learn==0.24.0
scipy==1.5.4
service-identity==18.1.0
six==1.15.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
sortedcontainers==2.3.0
scipy==1.7.1; python_version < '3.10' and python_version >= '3.7'
service-identity==21.1.0
six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
sortedcontainers==2.4.0
sqlparse==0.4.1; python_version >= '3.5'
threadpoolctl==2.1.0; python_version >= '3.5'
threadpoolctl==2.2.0; python_version >= '3.6'
tika==1.24
tqdm==4.59.0
twisted[tls]==21.2.0; python_full_version >= '3.5.4'
tqdm==4.62.1
twisted[tls]==21.7.0; python_full_version >= '3.6.7'
txaio==21.2.1; python_version >= '3.6'
tzlocal==2.1
urllib3==1.26.4; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'
uvicorn[standard]==0.13.4
uvloop==0.14.0
watchdog==1.0.2
typing-extensions==3.10.0.0
tzlocal==3.0; python_version >= '3.6'
urllib3==1.26.6; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'
uvicorn[standard]==0.15.0
uvloop==0.16.0
watchdog==2.1.3
watchgod==0.7
wcwidth==0.2.5
websockets==8.1
whitenoise==5.2.0
websockets==9.1
whitenoise==5.3.0
whoosh==2.7.4
zope.interface==5.3.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
zope.interface==5.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
+1 -1
View File
@@ -1,5 +1,5 @@
[Unit]
Description=Paperless consumer
Description=Paperless scheduler
Requires=redis.service
[Service]
+1 -1
View File
@@ -1,4 +1,4 @@
docker run -p 5432:5432 -e POSTGRES_PASSWORD=password -v paperless_pgdata:/var/lib/postgresql/data -d postgres:13
docker run -d -p 6379:6379 redis:latest
docker run -p 3000:3000 -d thecodingmachine/gotenberg
docker run -p 3000:3000 -d gotenberg/gotenberg:7
docker run -p 9998:9998 -d apache/tika
+4 -2
View File
@@ -25,7 +25,10 @@
"it-IT": "src/locale/messages.it_IT.xlf",
"ro-RO": "src/locale/messages.ro_RO.xlf",
"ru-RU": "src/locale/messages.ru_RU.xlf",
"es-ES": "src/locale/messages.es_ES.xlf"
"es-ES": "src/locale/messages.es_ES.xlf",
"pl-PL": "src/locale/messages.pl_PL.xlf",
"sv-SE": "src/locale/messages.sv_SE.xlf",
"lb-LU": "src/locale/messages.lb_LU.xlf"
}
},
"architect": {
@@ -70,7 +73,6 @@
"optimization": true,
"outputHashing": "none",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
+1 -1
View File
@@ -33,4 +33,4 @@ exports.config = {
}
}));
}
};
};
+54 -17
View File
@@ -188,35 +188,35 @@
<source>Confirm delete</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">204</context>
<context context-type="linenumber">206</context>
</context-group>
</trans-unit>
<trans-unit id="5382975254277698192" datatype="html">
<source>Do you really want to delete document &quot;<x id="PH" equiv-text="this.document.title"/>&quot;?</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">205</context>
<context context-type="linenumber">207</context>
</context-group>
</trans-unit>
<trans-unit id="6691075929777935948" datatype="html">
<source>The files for this document will be deleted permanently. This operation cannot be undone.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">206</context>
<context context-type="linenumber">208</context>
</context-group>
</trans-unit>
<trans-unit id="719892092227206532" datatype="html">
<source>Delete document</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">208</context>
<context context-type="linenumber">210</context>
</context-group>
</trans-unit>
<trans-unit id="1844801255494293730" datatype="html">
<source>Error deleting document: <x id="PH" equiv-text="JSON.stringify(error)"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">215</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="826b25211922a1b46436589233cb6f1a163d89b7" datatype="html">
@@ -1057,63 +1057,63 @@
<source>Title</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">85</context>
<context context-type="linenumber">88</context>
</context-group>
</trans-unit>
<trans-unit id="3100631071441658964" datatype="html">
<source>Title &amp; content</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">86</context>
<context context-type="linenumber">89</context>
</context-group>
</trans-unit>
<trans-unit id="7517688192215738656" datatype="html">
<source>ASN</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">87</context>
<context context-type="linenumber">90</context>
</context-group>
</trans-unit>
<trans-unit id="1010505078885609376" datatype="html">
<source>Advanced search</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">91</context>
</context-group>
</trans-unit>
<trans-unit id="2649431021108393503" datatype="html">
<source>More like</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">91</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="02d184c288f567825a1fcbf83bcd3099a10853d5" datatype="html">
<source>Filter tags</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
<context context-type="linenumber">20</context>
<context context-type="linenumber">19</context>
</context-group>
</trans-unit>
<trans-unit id="4b089ca12c472cf0b46167bb5afe4b527b301bbc" datatype="html">
<source>Filter correspondents</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
<context context-type="linenumber">28</context>
<context context-type="linenumber">27</context>
</context-group>
</trans-unit>
<trans-unit id="0ad509732aaf702b7ea8c771c7809fa84bc85908" datatype="html">
<source>Filter document types</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
<context context-type="linenumber">35</context>
<context context-type="linenumber">34</context>
</context-group>
</trans-unit>
<trans-unit id="2d9d55f1b70142ff4597ba32179d16888fd9c6b2" datatype="html">
<source>Reset filters</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
<context context-type="linenumber">58</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="7593728289020204896" datatype="html">
@@ -1205,7 +1205,7 @@
<source>Score:</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
<context context-type="linenumber">86</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="727d980bba2b3e0b3d8705607f1208eef046479b" datatype="html">
@@ -1407,11 +1407,19 @@
<context context-type="linenumber">68</context>
</context-group>
</trans-unit>
<trans-unit id="0f72a164f5a5d10d1fbdeeb84ac80a63c04b7e1b" datatype="html">
<source>Add item</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/select/select.component.html</context>
<context context-type="linenumber">11</context>
</context-group>
<note priority="1" from="description">Used for both types and correspondents</note>
</trans-unit>
<trans-unit id="a1e6c11f20d4bf6e8e6b43e3c6d2561b2080645e" datatype="html">
<source>Suggestions:</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/select/select.component.html</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">31</context>
</context-group>
</trans-unit>
<trans-unit id="27d158b47717ff9305d19866960418c603f19d55" datatype="html">
@@ -1421,6 +1429,13 @@
<context context-type="linenumber">3</context>
</context-group>
</trans-unit>
<trans-unit id="21fd41eb147f55ca26362f9c398e47733639837a" datatype="html">
<source>Add tag</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/tags/tags.component.html</context>
<context context-type="linenumber">11</context>
</context-group>
</trans-unit>
<trans-unit id="4eb84de23219c85432e38fb4fbdeb6c0f103ff8b" datatype="html">
<source>Show all</source>
<context-group purpose="location">
@@ -1724,11 +1739,25 @@
<context context-type="linenumber">100</context>
</context-group>
</trans-unit>
<trans-unit id="792060551707690640" datatype="html">
<source>Polish</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">101</context>
</context-group>
</trans-unit>
<trans-unit id="499386805970351976" datatype="html">
<source>Swedish</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">102</context>
</context-group>
</trans-unit>
<trans-unit id="4912706592792948707" datatype="html">
<source>ISO 8601</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">106</context>
<context context-type="linenumber">107</context>
</context-group>
</trans-unit>
<trans-unit id="2119857572761283468" datatype="html">
@@ -1875,6 +1904,14 @@
<context context-type="linenumber">23</context>
</context-group>
</trans-unit>
<trans-unit id="4460262093225954455" datatype="html">
<source>Search score</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/rest/document.service.ts</context>
<context context-type="linenumber">28</context>
</context-group>
<note priority="1" from="description">Score is a value returned by the full text search engine and specifies how well a result matches the given query</note>
</trans-unit>
<trans-unit id="4561076822163447092" datatype="html">
<source>Create new item</source>
<context-group purpose="location">
+20659 -4490
View File
File diff suppressed because it is too large. Load diff
+20 -20
View File
@@ -11,41 +11,41 @@
},
"private": true,
"dependencies": {
"@angular/animations": "~10.1.5",
"@angular/common": "~10.1.5",
"@angular/compiler": "~10.1.5",
"@angular/core": "~10.1.5",
"@angular/forms": "~10.1.5",
"@angular/localize": "~10.1.5",
"@angular/platform-browser": "~10.1.5",
"@angular/platform-browser-dynamic": "~10.1.5",
"@angular/router": "~10.1.5",
"@ng-bootstrap/ng-bootstrap": "^8.0.4",
"@ng-select/ng-select": "^5.0.9",
"@angular/animations": "~11.2.14",
"@angular/common": "~11.2.14",
"@angular/compiler": "~11.2.14",
"@angular/core": "~11.2.14",
"@angular/forms": "~11.2.14",
"@angular/localize": "~11.2.14",
"@angular/platform-browser": "~11.2.14",
"@angular/platform-browser-dynamic": "~11.2.14",
"@angular/router": "~11.2.14",
"@ng-bootstrap/ng-bootstrap": "^9.1.2",
"@ng-select/ng-select": "^7.0.0",
"bootstrap": "^4.5.0",
"file-saver": "^2.0.5",
"ng-bootstrap": "^1.6.3",
"ng2-pdf-viewer": "^6.3.2",
"ngx-bootstrap": "^6.2.0",
"ngx-color": "^6.2.0",
"ngx-cookie-service": "^10.1.1",
"ngx-file-drop": "^10.0.0",
"ngx-file-drop": "^11.1.0",
"ngx-infinite-scroll": "^9.1.0",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"uuid": "^8.3.1",
"zone.js": "~0.10.2"
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.1002.0",
"@angular/cli": "~10.1.5",
"@angular/compiler-cli": "~10.1.5",
"@types/jasmine": "~3.5.0",
"@angular-devkit/build-angular": "~0.1102.13",
"@angular/cli": "~11.2.14",
"@angular/compiler-cli": "~11.2.14",
"@types/jasmine": "~3.6.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.0.0",
"karma": "~6.3.3",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~4.0.0",
@@ -53,6 +53,6 @@
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.0.2"
"typescript": "~4.1.5"
}
}
+1 -1
View File
@@ -33,7 +33,7 @@ const routes: Routes = [
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
exports: [RouterModule]
})
export class AppRoutingModule { }
+1 -1
View File
@@ -1,3 +1,3 @@
<app-toasts></app-toasts>
<router-outlet></router-outlet>
<router-outlet></router-outlet>
+2 -2
View File
@@ -18,7 +18,7 @@ export class AppComponent implements OnInit, OnDestroy {
constructor (private settings: SettingsService, private consumerStatusService: ConsumerStatusService, private toastService: ToastService, private router: Router) {
let anyWindow = (window as any)
anyWindow.pdfWorkerSrc = '/assets/js/pdf.worker.min.js';
anyWindow.pdfWorkerSrc = 'assets/js/pdf.worker.min.js';
this.settings.updateDarkModeSettings()
}
@@ -45,7 +45,7 @@ export class AppComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.consumerStatusService.connect()
this.successSubscription = this.consumerStatusService.onDocumentConsumptionFinished().subscribe(status => {
if (this.showNotification(SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS)) {
this.toastService.show({title: $localize`Document added`, delay: 10000, content: $localize`Document ${status.filename} was added to paperless.`, actionName: $localize`Open document`, action: () => {
+7 -1
View File
@@ -63,6 +63,7 @@ import { LocalizedDateParserFormatter } from './utils/ngb-date-parser-formatter'
import { ApiVersionInterceptor } from './interceptors/api-version.interceptor';
import { ColorSliderModule } from 'ngx-color/slider';
import { ColorComponent } from './components/common/input/color/color.component';
import { DocumentAsnComponent } from './components/document-asn/document-asn.component';
import localeFr from '@angular/common/locales/fr';
import localeNl from '@angular/common/locales/nl';
@@ -73,7 +74,9 @@ import localeEnGb from '@angular/common/locales/en-GB';
import localeRo from '@angular/common/locales/ro';
import localeRu from '@angular/common/locales/ru';
import localeEs from '@angular/common/locales/es';
import { DocumentAsnComponent } from './components/document-asn/document-asn.component';
import localePl from '@angular/common/locales/pl';
import localeSv from '@angular/common/locales/sv';
import localeLb from '@angular/common/locales/lb';
registerLocaleData(localeFr)
@@ -86,6 +89,9 @@ registerLocaleData(localeEnGb)
registerLocaleData(localeRo)
registerLocaleData(localeRu)
registerLocaleData(localeEs)
registerLocaleData(localePl)
registerLocaleData(localeSv)
registerLocaleData(localeLb)
@NgModule({
declarations: [
@@ -30,7 +30,7 @@ export class ConfirmDialogComponent implements OnInit {
@Input()
buttonsEnabled = true
confirmButtonEnabled = true
seconds = 0
@@ -55,7 +55,7 @@
</button>
</div>
</div>
</div>
</div>
</div>
@@ -83,7 +83,7 @@ export class FilterableDropdownSelectionModel {
if (fireEvent) {
this.changed.next(this)
}
}
private getNonTemporary(id: number) {
@@ -10,7 +10,7 @@
<path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8z"/>
</svg>
</ng-container>
</div>
<div class="mr-1">
<app-tag *ngIf="isTag; else displayName" [tag]="item" [clickable]="true" linkTitle="Filter by tag"></app-tag>
@@ -11,7 +11,7 @@ export class AbstractInputComponent<T> implements OnInit, ControlValueAccessor {
constructor() { }
onChange = (newValue: T) => {};
onTouched = () => {};
writeValue(newValue: any): void {
@@ -2,4 +2,4 @@
<input type="checkbox" class="custom-control-input" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" (blur)="onTouched()" [disabled]="disabled">
<label class="custom-control-label" [for]="inputId">{{title}}</label>
<small *ngIf="hint" class="form-text text-muted">{{hint}}</small>
</div>
</div>
@@ -15,7 +15,7 @@ import { AbstractInputComponent } from '../abstract-input';
})
export class CheckComponent extends AbstractInputComponent<boolean> {
constructor() {
constructor() {
super()
}
@@ -5,12 +5,12 @@
<div class="input-group-prepend">
<span class="input-group-text" [style.background-color]="value">&nbsp;&nbsp;&nbsp;</span>
</div>
<ng-template #popContent>
<div style="min-width: 200px;" class="pb-3">
<color-slider [color]="value" (onChangeComplete)="colorChanged($event.color.hex)"></color-slider>
</div>
</ng-template>
<input class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [autoClose]="'outside'" [ngbPopover]="popContent" placement="bottom" popoverClass="shadow">
@@ -30,4 +30,4 @@
<div class="invalid-feedback">
{{error}}
</div>
</div>
</div>
@@ -11,4 +11,4 @@
</div>
<small *ngIf="hint" class="form-text text-muted">{{hint}}</small>
</div>
</div>
@@ -1,33 +1,38 @@
<div class="form-group paperless-input-select">
<label [for]="inputId">{{title}}</label>
<div [class.input-group]="showPlusButton()">
<ng-select name="inputId" [(ngModel)]="value"
[disabled]="disabled"
[style.color]="textColor"
[style.background]="backgroundColor"
[clearable]="allowNull"
[items]="items"
bindLabel="name"
bindValue="id"
(change)="onChange(value)"
(blur)="onTouched()">
</ng-select>
<div *ngIf="showPlusButton()" class="input-group-append">
<button class="btn btn-outline-secondary" type="button" (click)="createNew.emit()">
<svg class="buttonicon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#plus" />
</svg>
</button>
<div [class.input-group]="allowCreateNew">
<ng-select name="inputId" [(ngModel)]="value"
[disabled]="disabled"
[style.color]="textColor"
[style.background]="backgroundColor"
[clearable]="allowNull"
[items]="items"
[addTag]="allowCreateNew && addItemRef"
addTagText="Add item"
i18n-addTagText="Used for both types and correspondents"
bindLabel="name"
bindValue="id"
(change)="onChange(value)"
(search)="onSearch($event)"
(focus)="clearLastSearchTerm()"
(clear)="clearLastSearchTerm()"
(blur)="onBlur()">
</ng-select>
<div *ngIf="allowCreateNew" class="input-group-append">
<button class="btn btn-outline-secondary" type="button" (click)="addItem()">
<svg class="buttonicon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#plus" />
</svg>
</button>
</div>
</div>
</div>
<small *ngIf="hint" class="form-text text-muted">{{hint}}</small>
<small *ngIf="getSuggestions().length > 0">
<span i18n>Suggestions:</span>&nbsp;
<ng-container *ngFor="let s of getSuggestions()">
<a (click)="value = s.id; onChange(value)" [routerLink]="">{{s.name}}</a>&nbsp;
</ng-container>
</small>
</div>
@@ -16,6 +16,7 @@ export class SelectComponent extends AbstractInputComponent<number> {
constructor() {
super()
this.addItemRef = this.addItem.bind(this)
}
@Input()
@@ -34,9 +35,13 @@ export class SelectComponent extends AbstractInputComponent<number> {
suggestions: number[]
@Output()
createNew = new EventEmitter()
createNew = new EventEmitter<string>()
showPlusButton(): boolean {
public addItemRef: (name) => void
private _lastSearchTerm: string
get allowCreateNew(): boolean {
return this.createNew.observers.length > 0
}
@@ -48,4 +53,29 @@ export class SelectComponent extends AbstractInputComponent<number> {
}
}
addItem(name: string) {
if (name) this.createNew.next(name)
else this.createNew.next(this._lastSearchTerm)
this.clearLastSearchTerm()
}
clickNew() {
this.createNew.next(this._lastSearchTerm)
this.clearLastSearchTerm()
}
clearLastSearchTerm() {
this._lastSearchTerm = null
}
onSearch($event) {
this._lastSearchTerm = $event.term
}
onBlur() {
setTimeout(() => {
this.clearLastSearchTerm()
}, 3000);
}
}
@@ -7,8 +7,14 @@
[closeOnSelect]="false"
[clearSearchOnAdd]="true"
[hideSelected]="true"
[addTag]="createTagRef"
addTagText="Add tag"
i18n-addTagText
(change)="onChange(value)"
(blur)="onTouched()">
(search)="onSearch($event)"
(focus)="clearLastSearchTerm()"
(clear)="clearLastSearchTerm()"
(blur)="onBlur()">
<ng-template ng-label-tmp let-item="item">
<span class="tag-wrap tag-wrap-delete" (click)="removeTag(item.id)">
@@ -39,8 +45,8 @@
<ng-container *ngFor="let tag of getSuggestions()">
<a (click)="addTag(tag.id)" [routerLink]="">{{tag.name}}</a>&nbsp;
</ng-container>
</small>
</div>
@@ -17,8 +17,9 @@ import { TagService } from 'src/app/services/rest/tag.service';
})
export class TagsComponent implements OnInit, ControlValueAccessor {
constructor(private tagService: TagService, private modalService: NgbModal) { }
constructor(private tagService: TagService, private modalService: NgbModal) {
this.createTagRef = this.createTag.bind(this)
}
onChange = (newValue: number[]) => {};
@@ -56,6 +57,10 @@ export class TagsComponent implements OnInit, ControlValueAccessor {
tags: PaperlessTag[]
public createTagRef: (name) => void
private _lastSearchTerm: string
getTag(id) {
if (this.tags) {
return this.tags.find(tag => tag.id == id)
@@ -74,9 +79,11 @@ export class TagsComponent implements OnInit, ControlValueAccessor {
}
}
createTag() {
createTag(name: string = null) {
var modal = this.modalService.open(TagEditDialogComponent, {backdrop: 'static'})
modal.componentInstance.dialogMode = 'create'
if (name) modal.componentInstance.object = { name: name }
else if (this._lastSearchTerm) modal.componentInstance.object = { name: this._lastSearchTerm }
modal.componentInstance.success.subscribe(newTag => {
this.tagService.listAll().subscribe(tags => {
this.tags = tags.results
@@ -99,4 +106,18 @@ export class TagsComponent implements OnInit, ControlValueAccessor {
this.onChange(this.value)
}
clearLastSearchTerm() {
this._lastSearchTerm = null
}
onSearch($event) {
this._lastSearchTerm = $event.term
}
onBlur() {
setTimeout(() => {
this.clearLastSearchTerm()
}, 3000);
}
}
@@ -5,4 +5,4 @@
<div class="invalid-feedback">
{{error}}
</div>
</div>
</div>
@@ -12,4 +12,4 @@
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="cancelClicked()" i18n>Cancel</button>
<button type="button" class="btn btn-primary" (click)="selectClicked.emit(selected)" i18n>Select</button>
</div>
</div>
@@ -1,2 +1,2 @@
<span *ngIf="!clickable" class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</span>
<a [routerLink]="" [title]="linkTitle" *ngIf="clickable" class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</a>
<a [routerLink]="" [title]="linkTitle" *ngIf="clickable" class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</a>
@@ -23,7 +23,7 @@ export class StatisticsWidgetComponent implements OnInit, OnDestroy {
statistics: Statistics = {}
subscription: Subscription
private getStatistics(): Observable<Statistics> {
return this.http.get(`${environment.apiBaseUrl}statistics/`)
}
@@ -13,4 +13,4 @@
<p i18n>Consult the documentation on how to use these features. The section on basic usage also has some information on how to use paperless in general.</p>
</ng-container>
</app-widget-frame>
</app-widget-frame>
@@ -4,9 +4,9 @@
<h5 class="card-title mb-0">{{title}}</h5>
<ng-content select ="[header-buttons]"></ng-content>
</div>
</div>
<div class="card-body text-dark">
<ng-content select ="[content]"></ng-content>
</div>
</div>
</div>
@@ -60,9 +60,9 @@
<app-input-number i18n-title title="Archive serial number" [error]="error?.archive_serial_number" formControlName='archive_serial_number'></app-input-number>
<app-input-date i18n-title title="Date created" formControlName="created" [error]="error?.created"></app-input-date>
<app-input-select [items]="correspondents" i18n-title title="Correspondent" formControlName="correspondent" [allowNull]="true"
(createNew)="createCorrespondent()" [suggestions]="suggestions?.correspondents"></app-input-select>
(createNew)="createCorrespondent($event)" [suggestions]="suggestions?.correspondents"></app-input-select>
<app-input-select [items]="documentTypes" i18n-title title="Document type" formControlName="document_type" [allowNull]="true"
(createNew)="createDocumentType()" [suggestions]="suggestions?.document_types"></app-input-select>
(createNew)="createDocumentType($event)" [suggestions]="suggestions?.document_types"></app-input-select>
<app-input-tags formControlName="tags" [suggestions]="suggestions?.tags"></app-input-tags>
</ng-template>
@@ -139,7 +139,7 @@
<pdf-viewer [src]="previewUrl" [original-size]="false" [show-borders]="true" [show-all]="true" [(page)]="previewCurrentPage" [render-text-mode]="2" (after-load-complete)="pdfPreviewLoaded($event)"></pdf-viewer>
</div>
<ng-template #nativePdfViewer>
<object [data]="previewUrl | safe" type="application/pdf" class="preview-sticky" width="100%"></object>
<object [data]="previewUrl | safe" class="preview-sticky" width="100%"></object>
</ng-template>
</ng-container>
<ng-container *ngIf="getContentType() == 'text/plain'">
@@ -128,9 +128,10 @@ export class DocumentDetailComponent implements OnInit {
this.documentForm.patchValue(doc)
}
createDocumentType() {
createDocumentType(newName: string) {
var modal = this.modalService.open(DocumentTypeEditDialogComponent, {backdrop: 'static'})
modal.componentInstance.dialogMode = 'create'
if (newName) modal.componentInstance.object = { name: newName }
modal.componentInstance.success.subscribe(newDocumentType => {
this.documentTypeService.listAll().subscribe(documentTypes => {
this.documentTypes = documentTypes.results
@@ -139,9 +140,10 @@ export class DocumentDetailComponent implements OnInit {
})
}
createCorrespondent() {
createCorrespondent(newName: string) {
var modal = this.modalService.open(CorrespondentEditDialogComponent, {backdrop: 'static'})
modal.componentInstance.dialogMode = 'create'
if (newName) modal.componentInstance.object = { name: newName }
modal.componentInstance.success.subscribe(newCorrespondent => {
this.correspondentService.listAll().subscribe(correspondents => {
this.correspondents = correspondents.results
@@ -20,4 +20,4 @@
</tr>
</tbody>
</table>
</div>
</div>
@@ -1,3 +1,3 @@
.metadata-column {
overflow-wrap: anywhere;
}
}
@@ -82,7 +82,8 @@
</svg>
<small>{{document.created | customDate:'mediumDate'}}</small>
</div>
<div *ngIf="document.__search_hit__" class="list-group-item bg-light text-dark border-0 d-flex search-score">
<div *ngIf="document.__search_hit__?.score" class="list-group-item bg-light text-dark border-0 d-flex p-0 pl-4 search-score">
<small class="text-muted" i18n>Score:</small>
<ngb-progressbar [type]="searchScoreClass" [value]="document.__search_hit__.score" class="search-score-bar mx-2 mt-1" [max]="1"></ngb-progressbar>
</div>
@@ -64,4 +64,4 @@
span ::ng-deep .match {
color: black;
background-color: rgb(255, 211, 66);
}
}
@@ -75,15 +75,21 @@
</app-page-header>
<div class="w-100 mb-2 mb-sm-4">
<div class="sticky-top py-2 mt-n2 mt-sm-n3 py-sm-4 bg-body mx-n3 px-3">
<app-filter-editor [hidden]="isBulkEditing" [(filterRules)]="list.filterRules" [unmodifiedFilterRules]="unmodifiedFilterRules" #filterEditor></app-filter-editor>
<app-bulk-editor [hidden]="!isBulkEditing"></app-bulk-editor>
</div>
<div class="d-flex justify-content-between align-items-center">
<p>
<ng-container *ngIf="list.isReloading">
<div class="spinner-border spinner-border-sm mr-2" role="status"></div>
<ng-container i18n>Loading...</ng-container>
</ng-container>
<span i18n *ngIf="list.selected.size > 0">{list.collectionSize, plural, =1 {Selected {{list.selected.size}} of one document} other {Selected {{list.selected.size}} of {{list.collectionSize || 0}} documents}}</span>
<span i18n *ngIf="list.selected.size == 0">{list.collectionSize, plural, =1 {One document} other {{{list.collectionSize || 0}} documents}}</span>&nbsp;<span i18n *ngIf="isFiltered">(filtered)</span>
<ng-container *ngIf="!list.isReloading">
<span i18n *ngIf="list.selected.size == 0">{list.collectionSize, plural, =1 {One document} other {{{list.collectionSize || 0}} documents}}</span>&nbsp;<span i18n *ngIf="isFiltered">(filtered)</span>
</ng-container>
</p>
<ngb-pagination [pageSize]="list.currentPageSize" [collectionSize]="list.collectionSize" [(page)]="list.currentPage" [maxSize]="5"
[rotate]="true" aria-label="Default pagination"></ngb-pagination>
@@ -99,7 +105,7 @@
<app-document-card-large [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" *ngFor="let d of list.documents; trackBy: trackByDocumentId" [document]="d" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)" (clickDocumentType)="clickDocumentType($event)" (clickMoreLike)="clickMoreLike(d.id)">
</app-document-card-large>
</div>
<table class="table table-sm border shadow-sm" *ngIf="displayMode == 'details'">
<thead>
<th></th>
@@ -174,10 +180,10 @@
</tr>
</tbody>
</table>
<div class="m-n2 row row-cols-paperless-cards" *ngIf="displayMode == 'smallCards'">
<app-document-card-small [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" [document]="d" *ngFor="let d of list.documents; trackBy: trackByDocumentId" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)" (clickDocumentType)="clickDocumentType($event)"></app-document-card-small>
</div>
</ng-template>
@@ -34,3 +34,12 @@ $paperless-card-breakpoints: (
right: 0 !important;
left: auto !important;
}
.sticky-top {
z-index: 990; // below main navbar
top: calc(7rem - 2px); // height of navbar (mobile)
@media (min-width: 580px) {
top: 3.5rem; // height of navbar
}
}
@@ -2,14 +2,14 @@ import { Component, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren } from
import { ActivatedRoute, Router } from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { Subscription } from 'rxjs';
import { FilterRule } from 'src/app/data/filter-rule';
import { FilterRule, isFullTextFilterRule } from 'src/app/data/filter-rule';
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type';
import { PaperlessDocument } from 'src/app/data/paperless-document';
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
import { SortableDirective, SortEvent } from 'src/app/directives/sortable.directive';
import { ConsumerStatusService } from 'src/app/services/consumer-status.service';
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
import { DOCUMENT_SORT_FIELDS } from 'src/app/services/rest/document.service';
import { DOCUMENT_SORT_FIELDS, DOCUMENT_SORT_FIELDS_FULLTEXT } from 'src/app/services/rest/document.service';
import { SavedViewService } from 'src/app/services/rest/saved-view.service';
import { ToastService } from 'src/app/services/toast.service';
import { FilterEditorComponent } from './filter-editor/filter-editor.component';
@@ -52,7 +52,7 @@ export class DocumentListComponent implements OnInit, OnDestroy {
}
getSortFields() {
return DOCUMENT_SORT_FIELDS
return isFullTextFilterRule(this.list.filterRules) ? DOCUMENT_SORT_FIELDS_FULLTEXT : DOCUMENT_SORT_FIELDS
}
onSort(event: SortEvent) {
@@ -3,13 +3,12 @@
<div class="form-inline d-flex align-items-center">
<div class="input-group input-group-sm flex-fill w-auto">
<div class="input-group-prepend" ngbDropdown>
<button class="btn btn-outline-primary" ngbDropdownToggle>{{textFilterTargetName}}</button>
<button class="btn btn-outline-primary" ngbDropdownToggle>{{textFilterTargetName}}</button>
<div class="dropdown-menu shadow" ngbDropdownMenu>
<button *ngFor="let t of textFilterTargets" ngbDropdownItem [class.active]="textFilterTarget == t.id" (click)="changeTextFilterTarget(t.id)">{{t.name}}</button>
</div>
</div>
<input class="form-control form-control-sm" type="text" [(ngModel)]="textFilter" *ngIf="textFilterTarget != 'fulltext-morelike'">
<span class="form-control form-control-sm text-truncate" *ngIf="textFilterTarget == 'fulltext-morelike'">{{_moreLikeDoc?.title}}</span>
<input #textFilterInput class="form-control form-control-sm" type="text" [(ngModel)]="textFilter" [readonly]="textFilterTarget == 'fulltext-morelike'">
</div>
</div>
</div>
@@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, Output, OnInit, OnDestroy } from '@angular/core';
import { Component, EventEmitter, Input, Output, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core';
import { PaperlessTag } from 'src/app/data/paperless-tag';
import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent';
import { PaperlessDocumentType } from 'src/app/data/paperless-document-type';
@@ -72,6 +72,9 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
private documentService: DocumentService
) { }
@ViewChild("textFilterInput")
textFilterInput: ElementRef
tags: PaperlessTag[] = []
correspondents: PaperlessCorrespondent[] = []
documentTypes: PaperlessDocumentType[] = []
@@ -125,7 +128,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
@Input()
set filterRules (value: FilterRule[]) {
this._filterRules = value
this.documentTypeSelectionModel.clear(false)
this.tagSelectionModel.clear(false)
this.correspondentSelectionModel.clear(false)
@@ -159,6 +162,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
this.textFilterTarget = TEXT_FILTER_TARGET_FULLTEXT_MORELIKE
this.documentService.get(this._moreLikeId).subscribe(result => {
this._moreLikeDoc = result
this._textFilter = result.title
})
break
case FILTER_CREATED_AFTER:
@@ -286,8 +290,12 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
distinctUntilChanged()
).subscribe(text => {
this._textFilter = text
this.documentService.searchQuery = text
this.updateRules()
})
if (this._textFilter) this.documentService.searchQuery = this._textFilter
}
ngOnDestroy() {
@@ -325,7 +333,11 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
}
changeTextFilterTarget(target) {
if (this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_MORELIKE && target != TEXT_FILTER_TARGET_FULLTEXT_MORELIKE) {
this._textFilter = ""
}
this.textFilterTarget = target
this.textFilterInput.nativeElement.focus()
this.updateRules()
}
}
@@ -32,6 +32,6 @@ export class CorrespondentEditDialogComponent extends EditDialogComponent<Paperl
match: new FormControl(""),
is_insensitive: new FormControl(true)
})
}
}
}
@@ -18,7 +18,7 @@ export class CorrespondentListComponent extends GenericListComponent<PaperlessCo
constructor(correspondentsService: CorrespondentService, modalService: NgbModal,
private list: DocumentListViewService,
toastService: ToastService
) {
) {
super(correspondentsService,modalService,CorrespondentEditDialogComponent, toastService)
}
@@ -13,7 +13,7 @@ import { ToastService } from 'src/app/services/toast.service';
})
export class DocumentTypeEditDialogComponent extends EditDialogComponent<PaperlessDocumentType> {
constructor(service: DocumentTypeService, activeModal: NgbActiveModal, toastService: ToastService) {
constructor(service: DocumentTypeService, activeModal: NgbActiveModal, toastService: ToastService) {
super(service, activeModal, toastService)
}
@@ -49,4 +49,4 @@
</td>
</tr>
</tbody>
</table>
</table>
@@ -52,4 +52,4 @@
</td>
</tr>
</tbody>
</table>
</table>
@@ -5,4 +5,4 @@
<path d="M7 6.5C7 7.328 6.552 8 6 8s-1-.672-1-1.5S5.448 5 6 5s1 .672 1 1.5zm4 0c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S9.448 5 10 5s1 .672 1 1.5z"/>
</svg>
<h1 i18n>404 Not Found</h1>
</div>
</div>
+8 -2
View File
@@ -1,16 +1,22 @@
import { FILTER_FULLTEXT_MORELIKE, FILTER_FULLTEXT_QUERY } from "./filter-rule-type"
export function cloneFilterRules(filterRules: FilterRule[]): FilterRule[] {
if (filterRules) {
let newRules: FilterRule[] = []
for (let rule of filterRules) {
newRules.push({rule_type: rule.rule_type, value: rule.value})
}
return newRules
return newRules
} else {
return null
}
}
export function isFullTextFilterRule(filterRules: FilterRule[]): boolean {
return filterRules.find(r => r.rule_type == FILTER_FULLTEXT_QUERY || r.rule_type == FILTER_FULLTEXT_MORELIKE) != null
}
export interface FilterRule {
rule_type: number
value: string
}
}
@@ -1,7 +1,7 @@
import { MatchingModel } from './matching-model';
export interface PaperlessCorrespondent extends MatchingModel {
last_correspondence?: Date
}
@@ -1,5 +1,5 @@
export interface PaperlessDocumentMetadata {
original_checksum?: string
archived_checksum?: string
@@ -10,4 +10,4 @@ export interface PaperlessDocumentMetadata {
has_archive_version?: boolean
}
}
@@ -6,4 +6,4 @@ export interface PaperlessDocumentSuggestions {
document_types?: number[]
}
}
+1 -1
View File
@@ -15,4 +15,4 @@ export interface PaperlessSavedView extends ObjectWithId {
filter_rules: FilterRule[]
}
}
+1 -1
View File
@@ -3,5 +3,5 @@ export interface Results<T> {
count: number
results: T[]
}
@@ -8,4 +8,4 @@ export interface WebsocketConsumerStatusMessage {
message?: string
document_id: number
}
}
@@ -19,7 +19,7 @@ export class ApiVersionInterceptor implements HttpInterceptor {
'Accept': `application/json; version=${environment.apiVersion}`
}
})
return next.handle(request);
}
}
@@ -20,7 +20,7 @@ export class CsrfInterceptor implements HttpInterceptor {
let prefix = ""
if (this.meta.getTag('name=cookie_prefix')) {
prefix = this.meta.getTag('name=cookie_prefix').content
}
}
let csrfToken = this.cookieService.get(`${prefix?prefix:''}csrftoken`)
if (csrfToken) {
request = request.clone({
+4 -5
View File
@@ -11,12 +11,11 @@ const FORMAT_TO_ISO_FORMAT = {
@Pipe({
name: 'customDate'
})
export class CustomDatePipe extends DatePipe implements PipeTransform {
export class CustomDatePipe implements PipeTransform {
private defaultLocale: string
constructor(@Inject(LOCALE_ID) locale: string, private settings: SettingsService) {
super(locale)
constructor(@Inject(LOCALE_ID) locale: string, private datePipe: DatePipe, private settings: SettingsService) {
this.defaultLocale = locale
}
@@ -24,9 +23,9 @@ export class CustomDatePipe extends DatePipe implements PipeTransform {
let l = locale || this.settings.get(SETTINGS_KEYS.DATE_LOCALE) || this.defaultLocale
let f = format || this.settings.get(SETTINGS_KEYS.DATE_FORMAT)
if (l == "iso-8601") {
return super.transform(value, FORMAT_TO_ISO_FORMAT[f], timezone)
return this.datePipe.transform(value, FORMAT_TO_ISO_FORMAT[f], timezone)
} else {
return super.transform(value, format || this.settings.get(SETTINGS_KEYS.DATE_FORMAT), timezone, l)
return this.datePipe.transform(value, format || this.settings.get(SETTINGS_KEYS.DATE_FORMAT), timezone, l)
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
/**
* https://gist.github.com/JonCatmull/ecdf9441aaa37336d9ae2c7f9cb7289a
*
*
* @license
* Copyright (c) 2019 Jonathan Catmull.
*
+1 -1
View File
@@ -16,4 +16,4 @@ export class SafePipe implements PipeTransform {
}
}
}
}
@@ -125,7 +125,7 @@ export class ConsumerStatusService {
connect() {
this.disconnect()
this.statusWebSocket = new WebSocket(`${environment.webSocketProtocol}//${environment.webSocketHost}/ws/status/`);
this.statusWebSocket = new WebSocket(`${environment.webSocketProtocol}//${environment.webSocketHost}${environment.webSocketBaseUrl}status/`);
this.statusWebSocket.onmessage = (ev) => {
let statusMessage: WebsocketConsumerStatusMessage = JSON.parse(ev['data'])
@@ -1,28 +1,53 @@
import { Injectable } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { cloneFilterRules, FilterRule } from '../data/filter-rule';
import { FILTER_FULLTEXT_MORELIKE, FILTER_FULLTEXT_QUERY } from '../data/filter-rule-type';
import { cloneFilterRules, FilterRule, isFullTextFilterRule } from '../data/filter-rule';
import { PaperlessDocument } from '../data/paperless-document';
import { PaperlessSavedView } from '../data/paperless-saved-view';
import { DOCUMENT_LIST_SERVICE } from '../data/storage-keys';
import { DocumentService } from './rest/document.service';
import { SettingsService, SETTINGS_KEYS } from './settings.service';
/**
* Captures the current state of the list view.
*/
interface ListViewState {
/**
* Title of the document list view. Either "Documents" (localized) or the name of a saved view.
*/
title?: string
/**
* Current paginated list of documents displayed.
*/
documents?: PaperlessDocument[]
currentPage: number
/**
* Total amount of documents with the current filter rules. Used to calculate the number of pages.
*/
collectionSize: number
/**
* Currently selected sort field.
*/
sortField: string
/**
* True if the list is sorted in reverse.
*/
sortReverse: boolean
/**
* Filter rules for the current list view.
*/
filterRules: FilterRule[]
/**
* Contains the IDs of all selected documents.
*/
selected?: Set<number>
}
@@ -134,10 +159,10 @@ export class DocumentListViewService {
}
set filterRules(filterRules: FilterRule[]) {
this.activeListViewState.filterRules = filterRules
if (filterRules.find(r => (r.rule_type == FILTER_FULLTEXT_QUERY || r.rule_type == FILTER_FULLTEXT_MORELIKE))) {
this.activeListViewState.currentPage = 1
if (!isFullTextFilterRule(filterRules) && this.activeListViewState.sortField == "score") {
this.activeListViewState.sortField = "created"
}
this.activeListViewState.filterRules = filterRules
this.reload()
this.reduceSelectionToFilter()
this.saveDocumentListView()
@@ -213,6 +238,10 @@ export class DocumentListViewService {
this._activeSavedViewId = null
this.activeListViewState.filterRules = filterRules
this.activeListViewState.currentPage = 1
if (isFullTextFilterRule(filterRules)) {
this.activeListViewState.sortField = "score"
this.activeListViewState.sortReverse = false
}
this.reduceSelectionToFilter()
this.saveDocumentListView()
if (this.router.url == "/documents") {
@@ -10,7 +10,7 @@ export class OpenDocumentsService {
private MAX_OPEN_DOCUMENTS = 5
constructor(private documentService: DocumentService) {
constructor(private documentService: DocumentService) {
if (sessionStorage.getItem(OPEN_DOCUMENT_SERVICE.DOCUMENTS)) {
try {
this.openDocuments = JSON.parse(sessionStorage.getItem(OPEN_DOCUMENT_SERVICE.DOCUMENTS))
@@ -23,6 +23,11 @@ export const DOCUMENT_SORT_FIELDS = [
{ field: 'modified', name: $localize`Modified` }
]
export const DOCUMENT_SORT_FIELDS_FULLTEXT = [
...DOCUMENT_SORT_FIELDS,
{ field: 'score', name: $localize`:Score is a value returned by the full text search engine and specifies how well a result matches the given query:Search score` }
]
export interface SelectionDataItem {
id: number
document_count: number
@@ -39,6 +44,8 @@ export interface SelectionData {
})
export class DocumentService extends AbstractPaperlessService<PaperlessDocument> {
private _searchQuery: string
constructor(http: HttpClient, private correspondentService: CorrespondentService, private documentTypeService: DocumentTypeService, private tagService: TagService) {
super(http, 'documents')
}
@@ -92,6 +99,7 @@ export class DocumentService extends AbstractPaperlessService<PaperlessDocument>
getPreviewUrl(id: number, original: boolean = false): string {
let url = this.getResourceUrl(id, 'preview')
if (this._searchQuery) url += `#search="${this._searchQuery}"`
if (original) {
url += "?original=true"
}
@@ -138,4 +146,8 @@ export class DocumentService extends AbstractPaperlessService<PaperlessDocument>
return this.http.post(this.getResourceUrl(null, 'bulk_download'), {"documents": ids, "content": content}, { responseType: 'blob' })
}
public set searchQuery(query: string) {
this._searchQuery = query
}
}
@@ -44,7 +44,7 @@ export class SavedViewService extends AbstractPaperlessService<PaperlessSavedVie
tap(() => this.reload())
)
}
patchMany(objects: PaperlessSavedView[]): Observable<PaperlessSavedView[]> {
return combineLatest(objects.map(o => super.patch(o))).pipe(
tap(() => this.reload())
@@ -10,10 +10,10 @@ import { DocumentService } from './document.service';
providedIn: 'root'
})
export class SearchService {
constructor(private http: HttpClient) { }
autocomplete(term: string): Observable<string[]> {
return this.http.get<string[]>(`${environment.apiBaseUrl}search/autocomplete/`, {params: new HttpParams().set('term', term)})
}
}
}
+3 -1
View File
@@ -98,7 +98,9 @@ export class SettingsService {
{code: "ro-ro", name: $localize`Romanian`, englishName: "Romanian", dateInputFormat: "dd.mm.yyyy"},
{code: "ru-ru", name: $localize`Russian`, englishName: "Russian", dateInputFormat: "dd.mm.yyyy"},
{code: "es-es", name: $localize`Spanish`, englishName: "Spanish", dateInputFormat: "dd/mm/yyyy"},
{code: "pl-pl", name: $localize`Polish`, englishName: "Polish", dateInputFormat: "dd.mm.yyyy"},
{code: "sv-se", name: $localize`Swedish`, englishName: "Swedish", dateInputFormat: "yyyy-mm-dd"},
{code: "lb-lu", name: $localize`Luxembourgish`, englishName: "Luxembourgish", dateInputFormat: "dd.mm.yyyy"}
]
}
+2 -2
View File
@@ -6,7 +6,7 @@ function componentToHex(c) {
/**
* https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
*
*
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
@@ -45,4 +45,4 @@ function hslToRgb(h, s, l){
export function randomColor() {
let rgb = hslToRgb(Math.random(), 0.6, Math.random() * 0.4 + 0.4)
return `#${componentToHex(rgb[0])}${componentToHex(rgb[1])}${componentToHex(rgb[2])}`
}
}
Loaded 100 of 194 files, more files were not shown because too many files have changed in this diff. Show more