Compare commits

..

403 Commits

Author SHA1 Message Date
shamoon
1d17e24c6e Update version strings 2023-04-01 21:12:08 -07:00
shamoon
de155a753d Merge branch 'main' into dev 2023-04-01 21:08:33 -07:00
Trenton Holmes
1b4020b3d7 Fixes barcode tests not running 2023-04-01 17:38:18 -07:00
tooomm
b948750d55 Update README.md
Co-Authored-By: tooomm <tooomm@users.noreply.github.com>
2023-04-01 17:10:57 -07:00
Trenton H
ce41ac9158 Configures ruff as the one stop linter and resolves warnings it raised 2023-04-01 17:03:52 -07:00
dependabot[bot]
5869467db3 Merge pull request #2991 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/angular/common-15.2.5 2023-04-01 21:36:57 +00:00
dependabot[bot]
80472af53c Merge pull request #2993 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/types/node-18.15.11 2023-04-01 21:30:20 +00:00
shamoon
eaa6039082 Update angular packages 2023-04-01 14:24:21 -07:00
dependabot[bot]
03b84e7c43 Merge pull request #2992 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/ng-select/ng-select-10.0.4 2023-04-01 21:18:57 +00:00
dependabot[bot]
0ee8f5c498 Bump @types/node from 18.11.18 to 18.15.11 in /src-ui
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 18.11.18 to 18.15.11.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 21:18:21 +00:00
shamoon
41d15e8731 Merge pull request #2989 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/typescript-eslint/eslint-plugin-5.57.0
Bump @typescript-eslint/eslint-plugin from 5.50.0 to 5.57.0 in /src-ui
2023-04-01 14:17:32 -07:00
dependabot[bot]
bef081d353 Bump @ng-select/ng-select from 10.0.3 to 10.0.4 in /src-ui
Bumps [@ng-select/ng-select](https://github.com/ng-select/ng-select) from 10.0.3 to 10.0.4.
- [Release notes](https://github.com/ng-select/ng-select/releases)
- [Changelog](https://github.com/ng-select/ng-select/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ng-select/ng-select/compare/v10.0.3...v10.0.4)

---
updated-dependencies:
- dependency-name: "@ng-select/ng-select"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 20:59:48 +00:00
dependabot[bot]
a79045c064 Bump @angular/common from 15.2.1 to 15.2.5 in /src-ui
Bumps [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) from 15.2.1 to 15.2.5.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/15.2.5/packages/common)

---
updated-dependencies:
- dependency-name: "@angular/common"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 20:59:19 +00:00
dependabot[bot]
81341df635 Bump @typescript-eslint/eslint-plugin from 5.50.0 to 5.57.0 in /src-ui
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.50.0 to 5.57.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.57.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 20:58:01 +00:00
Trenton H
3c2bbf244d Creates a data model for the document consumption, allowing stronger typing of arguments and setting of some information about the file only once 2023-04-01 11:05:34 -07:00
shamoon
fa60251c18 Merge pull request #2983 from paperless-ngx/fix-2982
Fix: Use exclude instead of difference for mariadb
2023-03-31 14:39:13 -07:00
shamoon
5bd06494d5 Use exclude instead of difference for mariadb 2023-03-31 13:52:06 -07:00
shamoon
2fd217ef1f Fix doc detail button reset on error 2023-03-31 13:47:35 -07:00
Paperless-ngx Bot [bot]
d7068ca42b New Crowdin updates (#2688)
* New translations messages.xlf (Finnish)
[ci skip]

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

* New translations messages.xlf (Serbian (Latin))
[ci skip]
2023-03-30 19:56:48 -07:00
shamoon
f7b19cddbf Update messages.xlf 2023-03-30 19:53:52 -07:00
shamoon
62e756a11e Merge pull request #2818 from paperless-ngx/fix-2809
Fix: permissions display should not show users with inherited permissions & unable to change owner
2023-03-30 19:49:12 -07:00
shamoon
c992661a17 Merge pull request #2966 from paperless-ngx/feature-double-click
Feature: double-click docs
2023-03-30 18:40:37 -07:00
Trenton H
dde3205425 Merge pull request #2907 from margau/feature-multiple-barcode-scanners
feature: Add support for zxing as barcode scanning lib
2023-03-29 12:12:56 -07:00
Trenton H
15a264de3d Enables images to be release to Quay.io, alongside the existing registries 2023-03-29 11:35:57 -07:00
Trenton H
66929a9088 Merge remote-tracking branch 'origin/dev' into feature-multiple-barcode-scanners 2023-03-29 09:40:10 -07:00
shamoon
45c9518a6d Add visual feedback to table titles 2023-03-29 09:20:26 -07:00
shamoon
95d32dc0da Implement double-click documents 2023-03-28 23:26:13 -07:00
shamoon
d5ab1119d3 Fix heights on transitions, text/plain display in dark mode 2023-03-28 22:47:04 -07:00
shamoon
d9110f4ef7 Merge pull request #2949 from paperless-ngx/feature-test-mailaccount
Feature: test mail account
2023-03-25 23:38:01 -07:00
Trenton Holmes
5468394ef2 Disables mingle and gossip. Not useful with the single worker we use 2023-03-25 19:17:02 -07:00
Trenton Holmes
7ad21e0e45 Configures logging to capture celery and kombu debugging to library 2023-03-25 19:17:02 -07:00
shamoon
5012c0c97c Adds testing for test mail account 2023-03-24 15:14:02 -07:00
shamoon
698208fcd5 Add test mail account 2023-03-24 15:14:02 -07:00
Trenton H
e0d5fd9290 Unlock channels_redis and implement the workaround from the issue to use pub/sub instead 2023-03-23 19:54:19 -07:00
Trenton H
4bd1974911 Updates to the latest and still working pipenv version. Updates to latest wheels 2023-03-23 18:00:08 -07:00
Trenton H
d246e4090a Adds a tip for using tokens instead of passwords, now that support is integrated 2023-03-23 08:52:12 -07:00
shamoon
ff172f5ea1 Update is_token checkbox and frontend strings 2023-03-23 08:52:12 -07:00
Trenton H
09b1413748 Allows users to use OAuth tokens instead of passwords 2023-03-23 08:52:12 -07:00
shamoon
14b997fe2c Merge pull request #2938 from paperless-ngx/fix-2935
Fix: unable to edit correspondents (in `dev`)
2023-03-23 08:00:14 -07:00
shamoon
908b412a9a Update messages.xlf
[ci skip]
2023-03-23 07:59:13 -07:00
shamoon
cbd80615be Owner/name unique constraint violation should exclude self 2023-03-23 07:35:18 -07:00
shamoon
a9707f0ab0 Update permissions-select.component.ts
[ci skip]
2023-03-21 08:30:43 -07:00
Trenton H
4637e33326 Adds possible scary looking log line that is actually fine to troubleshooting 2023-03-21 07:46:57 -07:00
Trenton H
4a5f21dd87 Limit the number of threads waiting for files to be ready during polling 2023-03-21 07:46:57 -07:00
Trenton H
0778c2808b Instead of using PIL directly to convert TIFF to PDF, use the existing library of img2pdf 2023-03-20 13:48:05 -07:00
Marvin Gaube
567a1bb770 fix: skip tiff tests for zxing 2023-03-20 20:59:59 +01:00
Marvin Gaube
743ee886be feat: add tests for barcode scanner value checks 2023-03-20 20:31:50 +01:00
shamoon
20c6abae63 exclude current user from permissions retrieval users
Revert "exclude current user from permissions retrieval users"

This reverts commit 87efd0ccc8d4eb9d8acb614d22a5c95ffdb895ae.

Update permissions-user.component.ts
2023-03-19 23:41:36 -07:00
shamoon
ae0c585918 Fix inherited permissions should not display per user in permissions form 2023-03-19 23:41:36 -07:00
shamoon
4cfc416cdc Handle user saved and no longer has permissions 2023-03-19 23:39:52 -07:00
shamoon
9902c4745d fix doc detail discard perm changes 2023-03-19 23:39:52 -07:00
shamoon
e373ca7bdc fix unable to change owner to someone else 2023-03-19 23:39:52 -07:00
shamoon
6a34a35585 Merge pull request #2910 from paperless-ngx/feature-improved-statistics-widget
Feature: Improved statistics widget
2023-03-19 23:34:19 -07:00
shamoon
ee935a2988 Update dashboard.png 2023-03-19 23:33:11 -07:00
shamoon
0a977a9d0a Re-implement file type progress bar 2023-03-19 23:22:28 -07:00
Tobias Schürg
4d26a3d2c6 add file-types bar to statistics widget (#2914) 2023-03-19 21:06:59 -07:00
shamoon
276d11e4e8 Merge pull request #2904 from paperless-ngx/feature-improve-comments-ui
Enhancement: rename comments to notes and improve notes UI
2023-03-19 14:34:49 -07:00
Marvin Gaube
e89c0f15dd feature: Add support for zxing as barcode scanning lib 2023-03-19 13:48:35 +01:00
shamoon
2bdf0aae14 simplify character count query
Co-Authored-By: Trenton H <797416+stumpylog@users.noreply.github.com>
2023-03-18 14:31:27 -07:00
shamoon
2bc7f0b8e0 truncate long mime types + limit total types displayed 2023-03-18 14:25:37 -07:00
shamoon
bf8ae22f3f Rename comments --> notes 2023-03-18 13:59:17 -07:00
Markus Ongyerth
a5c6dab7c3 Allow psql client certificate authentication 2023-03-18 07:43:18 -07:00
shamoon
f3eedec402 Improved statistics widget 2023-03-18 01:51:18 -07:00
shamoon
741152dd50 Update bulk-editor.component.html
[ci skip]
2023-03-17 23:13:01 -07:00
shamoon
89c639f850 Just include comments on document object 2023-03-17 18:47:03 -07:00
shamoon
727fb38baf Frontend testing for new comment UI features 2023-03-17 18:47:03 -07:00
shamoon
e19dd2d527 Support navigating directly to comments 2023-03-17 18:47:03 -07:00
shamoon
9aa41b3524 Support control/command-enter submit comment form 2023-03-17 18:47:03 -07:00
shamoon
3911740360 Show number of comments on cards, tab 2023-03-17 18:47:03 -07:00
shamoon
f161722b34 Merge pull request #2893 from paperless-ngx/feature-enhanced-object-filtering
Enhancement: support filtering multiple correspondents, doctypes & storage paths
2023-03-17 18:46:22 -07:00
shamoon
adb956467b Add frontend testing of multi-object filtering 2023-03-17 17:57:54 -07:00
shamoon
00e17f4d69 Allow filtering on multiple correspondents, doctypes, storage paths
Preserve 'Not assigned' option
Fix default logical operator
Update frontend strings
Fix radio button name overlaps
Use include / exclude with multi-select for OneToOne objects
2023-03-17 17:57:54 -07:00
shamoon
dbe49b24df Merge pull request #2839 from paperless-ngx/handle-private-objects
Fix: frontend handle "private" tags, doctypes, correspondents
2023-03-17 00:21:19 -07:00
shamoon
7e75193f4a Update settings.component.ts
[ci skip]
2023-03-15 22:44:34 -07:00
Trenton H
96e8cfb765 Couple more documentation improvements 2023-03-15 10:40:10 -07:00
Trenton H
d47ca6109a Apply suggestions from code review
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-03-15 10:40:10 -07:00
Trenton H
8ac7d56fc5 Improve documentation around barcodes, re-organize configuration and update links 2023-03-15 10:40:10 -07:00
Trenton Holmes
bfaede26c4 Replace commas with underscores to handle Chrome issues with commas 2023-03-15 10:29:04 -07:00
Trenton H
477fd360f8 Unlock cryptography version now that PiWheels built the most recent version. Update in bulk. 2023-03-15 06:35:05 -07:00
shamoon
5b50870f21 Merge pull request #2885 from maxtruxa/fix-docs-master-main
Fix: Update outdated docs referencing master
2023-03-14 07:31:13 -07:00
Max Truxa
8161316c01 Fix: Update outdated docs referencing master
The `master` branch is now called `main`.
2023-03-14 10:19:00 +01:00
shamoon
3cb26722f1 Merge pull request #2880 from igrybkov/patch-1
Fix formatting in "Setup" documentation page
2023-03-13 09:06:55 -07:00
Illia Grybkov
7912f4a22a Fix formatting in "Setup" documentation page 2023-03-13 09:40:24 -05:00
Trenton Holmes
851b23fb09 Adds additional note for bare metal suggesting Redis be secured 2023-03-12 20:53:53 -07:00
Trenton H
849a108520 Changes the celery serializer to use pickle over json 2023-03-12 20:53:53 -07:00
Trenton Holmes
97ff2e126c Adds owner and original name to the possible naming schemes 2023-03-12 15:29:58 -07:00
shamoon
ef6c4e6789 Update frontend strings for mail rule filter_to 2023-03-12 10:31:42 -07:00
Trenton H
3e467c517d Allows filtering email by the TO value(s) as well 2023-03-12 10:31:42 -07:00
shamoon
70ac696f17 Merge pull request #2863 from paperless-ngx/feature-fix-2814
Fix: logout on change password via frontend
2023-03-11 19:57:02 -08:00
shamoon
39c80ded58 Merge pull request #2869 from bsvka/patch-1
Fix typo
2023-03-11 09:57:58 -08:00
bsvka
98782ca69d Fix typo 2023-03-11 18:06:12 +01:00
shamoon
c332eea354 Force logout on change own password 2023-03-11 00:36:09 -08:00
shamoon
41a3f039b5 Update messages.xlf
[ci skip]
2023-03-10 23:36:50 -08:00
shamoon
2d3cf43bc5 Merge pull request #2820 from paperless-ngx/fix-2812
Fix: give superuser full doc perms
2023-03-10 21:53:35 -08:00
Trenton H
7c90702ff7 Updates to libqpdf 11.3.0 2023-03-10 20:36:17 -08:00
shamoon
952cf11b9e Merge pull request #2855 from white-gecko/patch-1
Update docker-compose steps to support podman
2023-03-10 19:19:07 -08:00
Trenton H
4383550d98 When tagging an email using Gmail label extensions, append the label instead of replacing 2023-03-10 09:19:58 -08:00
shamoon
fcba2cca77 Update filter-editor.component.ts
[ci skip]
2023-03-10 08:38:27 -08:00
shamoon
2042b85056 Merge pull request #2827 from paperless-ngx/feature-owner-aware-unique-model-names
Feature: owner-aware unique model name constraint
2023-03-09 22:34:14 -08:00
Natanael Arndt
283a2ab648 Update docker-compose start steps
As also written in the docker-compose file it is necessary to do the steps in the order:

1. Run 'docker-compose pull'.
2. Run 'docker-compose run --rm webserver createsuperuser' to create a user.
3. Run 'docker-compose up -d'.
2023-03-09 22:30:55 +01:00
Trenton H
5e7b93d153 Comment up the testing a bit more 2023-03-09 08:43:31 -08:00
shamoon
c4ac35164b API should 400 on unique violations 2023-03-08 20:16:21 -08:00
shamoon
22a13981f3 Handle "private" tags, doctypes, correspondents 2023-03-08 19:07:47 -08:00
shamoon
29251b6e38 Add test coverage for owner-aware unique constraints 2023-03-08 19:07:32 -08:00
shamoon
b382f1412a Change model uniqueness from name to name+owner 2023-03-08 19:07:32 -08:00
shamoon
320537a054 Give superuser full doc permissions 2023-03-08 19:07:06 -08:00
shamoon
2fe7f8be46 TagViewSet should use PassUserMixin 2023-03-08 19:03:59 -08:00
Trenton H
f100198a8a Handle the possilbe case of splitting on an empty string returning a list with an empty string 2023-03-08 07:32:17 -08:00
Trenton Holmes
b470fc0140 Adds a utility for the settings to parse out a list, seperated by something, from an environment key 2023-03-08 07:32:17 -08:00
Trenton H
db02d5eff0 Ensure dates from emails are made timezone aware if not already 2023-03-07 10:01:40 -08:00
shamoon
9564a9c28d Merge pull request #2830 from tooomm/patch-1
docs: better language code help
2023-03-06 16:56:08 -08:00
shamoon
55295922c8 Merge pull request #2838 from tooomm/patch-3
Chore: Properly collapse `All Changes` section in releases
2023-03-06 15:21:26 -08:00
tooomm
c5b701f99d add hints to ocr languages installation 2023-03-06 23:58:32 +01:00
tooomm
3c606efc46 fix collapse-after setting 2023-03-06 23:40:20 +01:00
shamoon
cbab1a51f1 Hide selects when user doesnt have view permissions
[ci skip]
2023-03-06 11:07:40 -08:00
Trenton H
41bcfcaffe Changes out the settings and a decent amount of test code to be pathlib compatible 2023-03-06 09:16:07 -08:00
shamoon
7cb14374cf Update permissions-dialog.component.html
[ci skip]
2023-03-06 08:51:47 -08:00
shamoon
19b9fd0578 Merge pull request #2819 from paperless-ngx/fix-2815
Fix: disable bulk edit dialog buttons during operation
2023-03-06 08:50:08 -08:00
shamoon
d668c475de Merge pull request #2832 from tooomm/patch-2
Chore: Don't include changelog PR for different releases
2023-03-05 15:53:59 -08:00
tooomm
248f3f2181 don't append changelog PR to unrelated release 2023-03-05 16:36:24 +01:00
tooomm
bcd10f63ea better language code help 2023-03-05 16:03:42 +01:00
Jonas Winkler
db9733f0d5 Merge pull request #2808 from paperless-ngx/bugfix-database-locked-on-permission-change
fix database locked error
2023-03-04 16:25:51 +01:00
shamoon
e6aa213aa1 disable bulk edit permissions dialog buttons on submit 2023-03-03 19:32:39 -08:00
shamoon
f0fa726e71 Merge pull request #2813 from paperless-ngx/fix-2811
Fix: Disable suggestions for read-only docs
2023-03-03 15:36:43 -08:00
shamoon
ae46ef7add Disable suggestions for read-only docs 2023-03-03 15:21:02 -08:00
Jonas Winkler
c87ca25f22 fix database locked error 2023-03-03 23:30:12 +01:00
Jonas Winkler
ef627d53e5 Merge pull request #2806 from paperless-ngx/update-django-po-messages
update django.po messages
2023-03-03 20:45:10 +01:00
Jonas Winkler
d0fcf3607d update django.po messages 2023-03-03 20:16:57 +01:00
shamoon
3dbb7e5781 Merge pull request #2804 from paperless-ngx/fix-processed-mail-migration
Update processed mail migration
2023-03-03 11:11:54 -08:00
shamoon
9597358cb0 Update processed mail migration 2023-03-03 10:40:29 -08:00
shamoon
c5a21a3b0e Fix edit dialog error surfacing 2023-03-03 10:21:08 -08:00
shamoon
f56ccec77f Surface edit dialog errors all the way 2023-03-03 08:55:52 -08:00
shamoon
489340a338 Update admin.py 2023-03-02 19:37:09 -08:00
Jonas Winkler
e9e3d75383 Merge pull request #2718 from paperless-ngx/feature/2396-better-mail-actions
Feature/2396 better mail actions
2023-03-02 23:14:04 +01:00
Trenton H
74a1e5ed86 Disables creation of videos during testing with Cypress 2023-03-02 08:03:41 -08:00
Trenton H
3d961a3dbb Enable package caching for frontend testing 2023-03-02 08:03:41 -08:00
dependabot[bot]
604d56d0b8 Bump leonsteinhaeuser/project-beta-automations from 2.0.1 to 2.1.0
Bumps [leonsteinhaeuser/project-beta-automations](https://github.com/leonsteinhaeuser/project-beta-automations) from 2.0.1 to 2.1.0.
- [Release notes](https://github.com/leonsteinhaeuser/project-beta-automations/releases)
- [Commits](https://github.com/leonsteinhaeuser/project-beta-automations/compare/v2.0.1...v2.1.0)

---
updated-dependencies:
- dependency-name: leonsteinhaeuser/project-beta-automations
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 14:57:16 -08:00
shamoon
a82e259c1d Merge pull request #2793 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/zone.js-0.12.0
Bump zone.js from 0.11.8 to 0.12.0 in /src-ui
2023-03-01 14:31:39 -08:00
dependabot[bot]
34ef99a8ab Bump zone.js from 0.11.8 to 0.12.0 in /src-ui
Bumps [zone.js](https://github.com/angular/angular/tree/HEAD/packages/zone.js) from 0.11.8 to 0.12.0.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/packages/zone.js/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/zone.js-0.12.0/packages/zone.js)

---
updated-dependencies:
- dependency-name: zone.js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 22:10:43 +00:00
shamoon
fa389d19d0 Merge pull request #2792 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/typescript-eslint/parser-5.54.0
Bump @typescript-eslint/parser from 5.50.0 to 5.54.0 in /src-ui
2023-03-01 13:44:31 -08:00
shamoon
ebe70d996c Merge pull request #2788 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/angular/compiler-15.2.1
Bulk Bump angular packages to 15.2.1 in /src-ui
2023-03-01 13:41:22 -08:00
dependabot[bot]
e83e13fd57 Bulk bump angular to 15.2.1
Bump @angular/compiler from 15.1.2 to 15.2.1 in /src-ui

Bumps [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) from 15.1.2 to 15.2.1.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/15.2.1/packages/compiler)

---
updated-dependencies:
- dependency-name: "@angular/compiler"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 13:26:42 -08:00
dependabot[bot]
02362ae5e1 Bump @typescript-eslint/parser from 5.50.0 to 5.54.0 in /src-ui
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.50.0 to 5.54.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.54.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 21:00:01 +00:00
Jonas Winkler
e0f324f61c fix links in django admin 2023-03-01 18:17:55 +01:00
Trenton H
c422a081bf Be sure the scratch directory exists before using it as temporary directory 2023-03-01 07:13:31 -08:00
shamoon
72efb24b73 fix settings change detection on delete 2023-03-01 01:14:10 -08:00
shamoon
ee7653a8cd Make user_permissions not required 2023-03-01 00:33:01 -08:00
Jonas Winkler
020abaf7d6 Merge pull request #2777 from paperless-ngx/bugfix-owner-on-new-document
Don't submit owner via API on document upload
2023-03-01 01:08:54 +01:00
Jonas Winkler
6e2f6350e6 don't submit owner via API 2023-02-28 18:32:09 +01:00
Trenton Holmes
6b939f7567 Returns to using hashing against primary keys, at least for fields. Improves testing coverage 2023-02-28 08:13:10 -08:00
Trenton Holmes
c958a7c593 Changes from a hash based system to a time based system to prevent extra retrains 2023-02-28 08:13:10 -08:00
Trenton H
8709ea4df0 Changes classifier training to hold less data in memory at the same time 2023-02-28 08:13:10 -08:00
Trenton H
16d3041d7a Add new packages catagory for mypy typing stubs and configure some mypy settings in setup.cfg 2023-02-27 15:59:55 -08:00
shamoon
64b2037eda Update release-drafter.yml
[ci skip]
2023-02-27 11:46:43 -08:00
Jonas Winkler
4133001c73 Merge pull request #2743 from bdr99/ocr_skip_archive_file
Feature: Add PAPERLESS_OCR_SKIP_ARCHIVE_FILE config setting
2023-02-27 11:01:54 +01:00
Brandon Rothweiler
d5f46eedab Add tests for checks.py 2023-02-24 11:27:40 -05:00
Jonas Winkler
7a2a3e048e cleanup test code 2023-02-24 12:49:54 +01:00
Brandon Rothweiler
20891a370b Fix typo in deprecation log message 2023-02-23 22:52:31 -05:00
Brandon Rothweiler
ca412e0184 Add PAPERLESS_OCR_SKIP_ARCHIVE_FILE config setting 2023-02-23 22:42:57 -05:00
Brandon Rothweiler
8a89f5ae27 Revert "Merge pull request #2732 from bdr99/skip_neverarchive"
This reverts commit 77b23d3acb, reversing
changes made to 5d8aa27831.
2023-02-23 21:26:53 -05:00
shamoon
dbea2acc8f Merge pull request #2739 from paperless-ngx/fix-2738
Fix: only offer log files that exist
2023-02-23 15:32:29 -08:00
shamoon
65167625c4 Merge pull request #2704 from paperless-ngx/feature-dynamic-document-counts 2023-02-23 15:32:08 -08:00
shamoon
77b23d3acb Merge pull request #2732 from bdr99/skip_neverarchive
Feature: Add a setting to disable creating archive files
2023-02-23 15:22:49 -08:00
shamoon
5d8aa27831 Merge pull request #2717 from paperless-ngx/fix-user-perms-editing-issues
Fix: permissions editing and initial view issues
2023-02-23 15:19:53 -08:00
shamoon
b15eda9466 Merge pull request #2703 from paperless-ngx/fix-2702
Fix: reset saved view ID on quickFilter
2023-02-23 15:18:48 -08:00
Jonas Winkler
5eb4b975ae fix the test cases for python 3.8 2023-02-24 00:15:40 +01:00
Jonas Winkler
3ce1e01d96 fix the test cases 2023-02-24 00:03:28 +01:00
Trenton H
afcefe3d04 Fixes creation of the paperless.conf in the release dist 2023-02-23 14:59:34 -08:00
shamoon
4726fe8b6f Only return logs that exist 2023-02-23 14:43:43 -08:00
Jonas Winkler
201a4a7ef9 changes 2023-02-23 22:02:38 +01:00
Brandon Rothweiler
93a6391f96 Add a setting to disable creating an archive file 2023-02-22 15:27:17 -05:00
shamoon
782db3f324 Merge pull request #2727 from bdr99/disable-matching
Feature: Add an option to disable matching
2023-02-22 07:13:27 -08:00
Brandon Rothweiler
7610a0459e Add test 2023-02-22 09:39:29 -05:00
shamoon
927616decb Reorder frontend matching model options & update strings 2023-02-21 20:58:52 -08:00
Brandon Rothweiler
8b2b7bbe6d Add an option to disable matching 2023-02-21 20:01:30 -05:00
shamoon
ca30dbc832 Update translation strings 2023-02-21 13:26:40 -08:00
Jonas Winkler
3c3c847db5 reconfigure mail admin 2023-02-21 22:07:14 +01:00
Jonas Winkler
b7a2601724 Merge branch 'dev' into feature/2396-better-mail-actions 2023-02-21 18:37:17 +01:00
Jonas Winkler
1189df1fe6 changes 2023-02-21 18:37:08 +01:00
Jonas Winkler
a37177703c mark mails as processed internally, don't process processed mails again 2023-02-21 13:50:34 +01:00
Trenton H
8df1324afd Updates the latest test to use status codes 2023-02-20 10:25:21 -08:00
Trenton Holmes
a6e2708605 Changes testing to use more declarative status code names from DRF 2023-02-20 10:25:21 -08:00
Trenton Holmes
0df91c31f1 Creates a mix-in for asserting file system states 2023-02-20 10:25:21 -08:00
shamoon
1718cf6504 prevent edit docs when dont have global edit perms 2023-02-20 08:20:37 -08:00
Trenton Holmes
bec8d00232 Allow setting the ASN on document upload 2023-02-20 07:56:37 -08:00
Trenton Holmes
1471dd72a6 Bulk update of all Python libraries 2023-02-20 07:15:48 -08:00
shamoon
588a786d73 Fix startup without saved view permissions 2023-02-20 03:10:03 -08:00
Jonas Winkler
7e1c1da424 remove unused argument 2023-02-20 11:57:56 +01:00
Jonas Winkler
94ebe3b61c implement better mail actions 2023-02-20 11:46:46 +01:00
shamoon
75c5ccccec Fix dyanmic disabling checkboxes in permissions select 2023-02-20 02:15:11 -08:00
shamoon
eb4c8e1b1e Fix inherited permissions being set at user level & unable to unselect existing perms 2023-02-20 01:27:44 -08:00
shamoon
73b1b942a9 Merge pull request #2701 from paperless-ngx/fix-bulk-edit-reset-apply-button
Fix: bulk edit reset apply button state
2023-02-19 18:40:14 -08:00
Jonas Winkler
8c5ef111d8 Merge branch 'dev' into feature/2396-better-mail-actions 2023-02-19 23:29:52 +01:00
shamoon
b6266ad18f Live document counts for document filtering 2023-02-18 20:07:33 -08:00
shamoon
2635c3a1a0 Live document counts for bulk edit 2023-02-18 20:07:07 -08:00
shamoon
13ece25de0 Merge pull request #2359 from paperless-ngx/feature-log-failed-auth
Feature: Log failed login attempts
2023-02-18 19:40:51 -08:00
shamoon
c69ece1d0e Fix: reset saved view ID on quickFilter 2023-02-18 18:36:19 -08:00
Trenton H
07ec6ff7ab Adds some quick testing of the IP logging during a failed login 2023-02-18 15:26:09 -08:00
shamoon
66e23bd356 Fix apply button should reset state on close dropdown 2023-02-18 14:29:49 -08:00
Trenton H
abc58000b4 Moves the renaming ttask into the serialiser update instead of post_save. Feels more correct 2023-02-18 12:19:33 -08:00
Trenton H
5e3ef94697 Moves the renaming triggered from a storage path change to be a background task 2023-02-18 12:19:33 -08:00
shamoon
2daee375d0 Remove obsolete UI warning on edit storage path 2023-02-18 12:19:33 -08:00
Trenton H
857944aabe When a StoragePath is changed, check if related documents require a rename 2023-02-18 12:19:33 -08:00
Trenton H
72f58d54a3 Moves django-ipware up to be with other Django libraries 2023-02-17 08:12:27 -08:00
Michael Shamoon
668b068bb5 Log failed login attempts 2023-02-17 08:12:27 -08:00
shamoon
9893ae9880 Merge pull request #2689 from paperless-ngx/feature-update-error-messages
Feature: update error message colors & show on document failures
2023-02-17 07:52:31 -08:00
shamoon
9cdf2f046f Make error message toasts more visually distinct 2023-02-17 07:51:21 -08:00
shamoon
f7f841ce6d Show errors on document save 2023-02-17 07:51:21 -08:00
shamoon
e8a52d48cf Merge pull request #2694 from paperless-ngx/fix-2693 2023-02-17 07:40:37 -08:00
shamoon
21eb253c57 Merge pull request #2147 from paperless-ngx/feature-permissions
Feature: multi-user permissions
2023-02-17 07:21:18 -08:00
shamoon
754286cb9a Merge pull request #2692 from nathanaelhoun/fix-missing-i18n-for-mobile-preview
fix: add missing i18n for mobile "preview" pane
2023-02-17 07:19:05 -08:00
Nathanaël Houn
08f5d9a92f docs: fix command used for i18n extraction 2023-02-17 07:14:14 -08:00
shamoon
a1a61000ab Remove outdated PAPERLESS_WORKER_RETRY 2023-02-17 07:07:13 -08:00
Nathanaël Houn
dd91d4264a fix: added missing i18n placeholder for file preview 2023-02-17 14:08:05 +01:00
shamoon
9d87ac5244 Update messages.xlf 2023-02-16 20:45:11 -08:00
shamoon
3559e27cdd Merge branch 'dev' into feature-permissions 2023-02-16 20:44:51 -08:00
shamoon
4b9c79fa07 Update messages.xlf 2023-02-16 20:44:02 -08:00
shamoon
ee197bf89f Add dev tag to dev version 2023-02-16 20:43:14 -08:00
shamoon
31dac60d04 Merge pull request #2690 from paperless-ngx/v1.13.0-changelog
[Documentation] Add v1.13.0 changelog
2023-02-16 20:42:01 -08:00
github-actions
75a7dd38a1 Changelog v1.13.0 - GHA 2023-02-16 20:38:57 -08:00
shamoon
6c658a676e Bumps version to 1.13.0 2023-02-16 20:10:35 -08:00
shamoon
38de2a7767 Merge branch 'dev' 2023-02-16 20:07:50 -08:00
Jonas
d7cb7c78af adjust mail workflow, execute mail actions only after consumption is successful 2023-02-16 22:51:46 +01:00
Trenton H
ee272da95f Instead of pulling all images, inspect the manifest index and each digest index 2023-02-16 13:03:24 -08:00
shamoon
8098ac6b15 Merge pull request #2681 from paperless-ngx/feature-2162
Feature: allow disable warn on close saved view with changes
2023-02-16 09:59:42 -08:00
Trenton H
c08f0054da Updates ignore path filtering so files in a folder in an ignored folder will be ignored correctly 2023-02-16 09:05:11 -08:00
shamoon
29f8cda104 Allow disable saved view with unsaved changes warning 2023-02-16 07:12:09 -08:00
Trenton Holmes
0d1a8d6d2f Resolves the subshell not returnning when generating SECRET_KEY 2023-02-14 17:20:34 -08:00
Paperless-ngx Translation Bot [bot]
edfd3bbe91 New Crowdin updates (#2527)
* New translations django.po (Dutch)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (Portuguese, Brazilian)
[ci skip]

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

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

* New translations messages.xlf (Serbian (Latin))
[ci skip]
2023-02-14 12:02:29 -08:00
shamoon
148f394679 Update frontend strings 2023-02-14 11:53:10 -08:00
shamoon
b91ec5a520 Update frontend strings 2023-02-14 11:52:30 -08:00
shamoon
f57873fb1b Merge branch 'dev' into feature-permissions 2023-02-14 11:35:48 -08:00
shamoon
32754defef Merge branch 'dev' into feature-permissions 2023-02-14 11:32:37 -08:00
Trenton H
0d777343fb Changes the default setting for compression to enabled 2023-02-12 14:45:51 -08:00
Trenton H
3b0fa4f707 Adds option to enable compression of webserver responses 2023-02-12 14:45:51 -08:00
Trenton Holmes
8b3d01c49b When splitting via barcodes, cleanup the split documents better 2023-02-12 08:20:12 -08:00
shamoon
1d5eb983ea Merge pull request #2651 from paperless-ngx/fix-2650
Fix: add missing storage path placeholders
2023-02-12 07:55:27 -08:00
shamoon
add647afe6 Add missing storage path placeholders 2023-02-12 02:01:44 -08:00
Trenton Holmes
3e777f2a5b Fixes up some minor warnings from test code 2023-02-11 14:35:16 -08:00
Omar Saleem
7bfb11a711 adding quotes around port 'find' field as requested 2023-02-10 15:14:22 -08:00
Omar Saleem
808cf93a19 need quotes in install script too 2023-02-10 15:14:22 -08:00
Omar Saleem
37ddc3b8f7 wrapping ports in quotes 2023-02-10 15:14:22 -08:00
shamoon
bc91b830ed Merge pull request #2638 from paperless-ngx/fix-2637
Fix long dropdown contents break document detail column view
2023-02-10 11:51:28 -08:00
shamoon
ced248ad49 Fix toggle split doesnt have rounded right corner 2023-02-09 20:17:00 -08:00
shamoon
d73fbb1643 Fix long dropdown contents break column layout 2023-02-09 20:16:45 -08:00
Trenton H
40db244d4a Fixes the test for expiration 2023-02-08 09:47:56 -08:00
Trenton H
8181535f40 Fixes expiration of the weekly task 2023-02-08 09:33:46 -08:00
shamoon
2d9fa58157 Merge pull request #2625 from paperless-ngx/fix-2465
Fix: tags dropdown should stay closed when removing
2023-02-08 08:26:17 -08:00
Trenton H
7af0b47ba9 Expire the scheduled tasks shortly a new one will be added to the queue by default 2023-02-08 08:18:11 -08:00
Trenton H
b9f0418038 Fixes flower not respecting its config location, and a little more info to the user 2023-02-08 08:18:11 -08:00
shamoon
74b729bf5a tags dropdown doesnt need to open upon removal 2023-02-07 15:44:15 -08:00
Trenton H
66333caebc Fixes all Python versions uploading to Codecov 2023-02-06 10:02:15 -08:00
shamoon
405c0922f8 Merge pull request #2618 from paperless-ngx/feature-management-list-pagination
Bugfix: Limit management list pagination maxSize to 5
2023-02-06 08:19:33 -08:00
shamoon
bdf9b2453f Merge pull request #2608 from paperless-ngx/compatibility-updates-0222 2023-02-06 07:51:48 -08:00
Bastien KERVICHE
8ef5f0e93c fix: limit pagination in management-list 2023-02-06 11:21:10 +01:00
Trenton H
597bb98cb9 Updates to the expected PDF minus an extra whitespace 2023-02-05 20:17:22 -08:00
shamoon
cc971a4569 Note possible utf8mb3 requirement 2023-02-05 20:17:22 -08:00
shamoon
8955d25a00 update gotenberg to 7.8 2023-02-05 20:17:22 -08:00
Trenton H
bdcba570cb Adding more test coverage, in particular around Tika and its parser 2023-02-05 11:01:55 -08:00
shamoon
0e83c94832 Resolve migration conflicts 2023-02-03 14:25:22 -08:00
shamoon
d2a6f79612 Merge branch 'dev' into feature-permissions 2023-02-03 14:23:50 -08:00
shamoon
8154c7b53a Migration required for rename of PaperlessTask field 2023-02-03 13:54:39 -08:00
shamoon
ac611acaa1 Correct PaperlessTask model field verbose name
Closes #2597
2023-02-03 13:49:46 -08:00
Trenton H
faecd59432 Increment the index version for Docker users 2023-02-03 08:31:45 -08:00
Trenton H
0f536a9b9a Detect and reset invalid ASNs to 0 during indexing with a loud error to the user 2023-02-03 08:31:45 -08:00
Trenton H
a203b006e7 Adjust permissions of the final dist package to the normal first user of a system, instead of runner:docker 2023-02-02 17:09:37 -08:00
Trenton H
5978650ec6 Note that changing STATIC_ROOT may require running collectstatic again 2023-02-02 17:09:37 -08:00
Trenton H
8fea4c00ad Improves and clarifies the release distribution steps. No changes to static copying 2023-02-02 17:09:37 -08:00
Trenton H
9b3ec22beb Don't forget to remove the zipped binaries file after install 2023-02-02 17:09:37 -08:00
Trenton H
54e1c17539 Link to the the compiled frontend instead of copying it during collectstatic 2023-02-02 17:09:37 -08:00
Trenton H
06e2500443 Moves the mktime call into the if block where it is used, preventing exceptions during rare cases 2023-02-02 07:25:32 -08:00
dependabot[bot]
f43c3e0dd6 Merge pull request #2577 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/typescript-eslint/parser-5.50.0 2023-02-02 06:31:17 +00:00
shamoon
73b2c366df Batch update npm packages 2023-02-01 22:20:59 -08:00
Trenton H
1547a698cb Switches to Codecov for coverage reporting and status 2023-02-01 17:49:28 -08:00
dependabot[bot]
87b1f5adec Bump docker/build-push-action from 3 to 4
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3 to 4.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-01 12:14:27 -08:00
dependabot[bot]
8a281452b8 Bump @typescript-eslint/parser from 5.48.1 to 5.50.0 in /src-ui
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.48.1 to 5.50.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.50.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-01 20:02:50 +00:00
shamoon
dd38b84116 Merge pull request #2570 from paperless-ngx/chore-convert-testing
Chore: Run tests which require `convert` in the CI
2023-02-01 01:14:37 -08:00
Fabian Ohler
658d372cd2 Feature: split documents on ASN barcode (#2554)
* also split documents when an ASN barcode is found

* linter

* fix test case parameters

* avoid pre-python-3.9 features

* simplify dict-creation in tests

* simplify dict-creation in tests for empty dicts

* Add test cases for the splitting by ASN barcode feature

* deleted supporting files for test case construction
2023-02-01 01:13:30 -08:00
Trenton Holmes
61f7e73961 Fixes status payload filename after splitting 2023-01-31 20:48:35 -08:00
Trenton H
31bcb613ad Configure ImageMagick on the runner to allow more tests to run by default 2023-01-31 14:37:56 -08:00
Trenton H
b85d39b189 Fixes commenting error 2023-01-31 12:53:46 -08:00
Trenton H
dc7bef5d48 Fixes relative date Whoosh queries and adds testing to ensure it remains working with multiple timezones 2023-01-31 12:53:46 -08:00
Kexogg
dae4550bc3 Fix importing files with non-ascii names (#2555) 2023-01-31 11:33:06 -08:00
shamoon
dace08d4e3 Merge pull request #2562 from paperless-ngx/fix/extra-docker-installs
Chore: Remove Docker image extra Python installs
2023-01-30 16:32:57 -08:00
shamoon
c42a9b8b8f Merge pull request #2563 from paperless-ngx/upgrade-supervisord
Chore: Upgrades supervisor to 4.2.5
2023-01-30 16:32:34 -08:00
Trenton H
94db39e055 A few minor tweaks to the backend 2023-01-30 14:37:09 -08:00
Trenton H
9ee324915f Upgrades supervisor to 4.2.5 2023-01-30 11:35:04 -08:00
Trenton H
bb211ee779 Removes extra install of Python and pip. The base image provides these 2023-01-30 11:27:18 -08:00
shamoon
00c3d8c523 Merge pull request #2553 from paperless-ngx/v1.12.2-changelog
[Documentation] Add v1.12.2 changelog
2023-01-29 20:05:26 -08:00
shamoon
4f0d2cd612 Move reindex note to v1.12.2 2023-01-29 09:24:12 -08:00
github-actions
f4304a120b Changelog v1.12.2 - GHA 2023-01-29 17:07:04 +00:00
Trenton Holmes
b8c3e564c6 Reset to -dev version tag 2023-01-29 08:52:01 -08:00
Trenton Holmes
0a47fba9ae Bumps version to 1.12.2 2023-01-29 08:42:23 -08:00
Trenton Holmes
9aea8a7d7c Merge remote-tracking branch 'origin/dev' 2023-01-29 08:40:13 -08:00
Trenton Holmes
7b9c0d65b9 Documents the change to pre-consume script and improves the readability 2023-01-29 08:37:32 -08:00
Trenton H
7dd9a4e089 Changes the consumer to work on a temporary copy and provies that copy to the pre-consume script for modifications 2023-01-29 08:37:32 -08:00
Michael Shamoon
d15773f282 Merge branch 'dev' into feature-permissions 2023-01-27 12:35:48 -08:00
Trenton H
9784ea4a60 Minor tweak to password test to ensure the right lines were hit 2023-01-27 12:24:47 -08:00
Trenton H
4fce5aba63 Moves ASN barcode testing into a dedicated class 2023-01-27 12:24:47 -08:00
Trenton H
2ab77fbaf7 Removes pikepdf based scanning, fixes up unit testing (+ commenting) 2023-01-27 12:24:47 -08:00
shamoon
94ad290e14 Merge pull request #2543 from paperless-ngx/feature-improved-title-debounce
Fix: Try to prevent title debounce overwriting
2023-01-27 12:24:07 -08:00
Michael Shamoon
118e3703dc Disable redo OCR without edit permissions 2023-01-27 12:21:45 -08:00
shamoon
d2b290f789 Merge pull request #2542 from paperless-ngx/fix-2536
Fix comment search highlight + multi-word search
2023-01-27 11:08:36 -08:00
Trenton H
583f05af2d Fixes test parameters 2023-01-27 11:05:23 -08:00
Trenton H
1b2cb13a21 Adds setting to Gotenberg API call for outputting the correct PDF/A format 2023-01-27 11:05:23 -08:00
Michael Shamoon
4dc0c7bbe2 Better display of multiple comment hits 2023-01-27 10:29:40 -08:00
Michael Shamoon
44212d492d Fix whoosh auto-highlighting for comments 2023-01-27 10:20:24 -08:00
Trenton H
3ccb83e49c Restores deletion 2023-01-27 10:00:55 -08:00
Trenton H
215691ac1a Changes the still pull check to be using Python Docker SDK 2023-01-27 10:00:55 -08:00
Trenton H
a884647a7c Changes to use buildx imagetools to extract the manifest, supporting new attestation manifests 2023-01-27 10:00:55 -08:00
Michael Shamoon
590d129cd3 Fix typo, update translation strings 2023-01-27 09:36:54 -08:00
Trenton Holmes
8fcb7efbd2 Adds some basic steps for updating 2023-01-26 15:47:26 -08:00
Trenton H
f1204d2749 Updates the installer library to be static in the final image, saving the installers into Git and curl-ing the correct revision 2023-01-26 15:47:26 -08:00
Michael Shamoon
b07b8d65a6 Fix note indentation in dev docs 2023-01-26 12:43:19 -08:00
shamoon
dadd7472fd Merge pull request #2519 from paperless-ngx/force-reindex-for-comments
Fix: Trigger reindex for pre-existing comments
2023-01-26 07:46:00 -08:00
clemensrieder
2801b60b0e Minor updates to development documentation (#2474)
* clarify commands by adding paths

* fix trailing space in header

* rerun pre-commit

* one last time :S

* update sections, remove duplicate information

* those pesky pre-commits ;-)

* implement suggestions
2023-01-26 07:45:35 -08:00
Michael Shamoon
e625ac21c3 Update index version to force reindex, note in release notes 2023-01-25 20:30:48 -08:00
Michael Shamoon
7ace9eb325 Merge branch 'main' into dev 2023-01-25 20:22:21 -08:00
shamoon
02465672f9 Merge pull request #2515 from paperless-ngx/v1.12.1-changelog
[Documentation] Add v1.12.1 changelog
2023-01-25 14:07:06 -08:00
Michael Shamoon
9b1b620a9c Include group model in frontend permissions 2023-01-25 14:03:45 -08:00
github-actions
6ea6c79575 Changelog v1.12.1 - GHA 2023-01-25 21:02:01 +00:00
Trenton H
c430b9f8cf Resets version to -dev tagging 2023-01-25 12:29:57 -08:00
Michael Shamoon
f78e93a364 Try to prevent title debounce overwriting 2023-01-25 10:53:08 -08:00
Michael Shamoon
6d3feaebfd Merge branch 'dev' into feature-permissions 2023-01-25 09:58:36 -08:00
Michael Shamoon
781929e9a8 Add permissions docs 2023-01-25 09:37:49 -08:00
Michael Shamoon
5fc7c15039 Fix conflicting migrations from dev 2023-01-24 14:23:01 -08:00
Michael Shamoon
44f860d9b0 Merge branch 'dev' into feature-permissions 2023-01-24 14:10:45 -08:00
shamoon
0cfa5211e9 Merge branch 'dev' into feature-permissions 2023-01-16 15:59:25 -08:00
Michael Shamoon
d689a707a4 Update Pipfile.lock 2023-01-06 18:09:42 -08:00
Michael Shamoon
55e1745889 Merge branch 'dev' into feature-permissions 2023-01-06 18:04:00 -08:00
Michael Shamoon
43ec058593 Update Pipfile.lock 2023-01-05 19:47:25 -08:00
Michael Shamoon
a4d96061de Merge branch 'dev' into feature-permissions 2023-01-05 19:45:12 -08:00
Michael Shamoon
f1eecd146d include email + pw for frontend user editing 2023-01-03 08:29:36 -08:00
Michael Shamoon
1663450c1f include owner on mailrule / account creation 2023-01-01 21:13:08 -08:00
Michael Shamoon
d840308392 fix merge conflict for edit dialog succeeded and pw not required 2023-01-01 17:55:52 -08:00
Michael Shamoon
a08467342c Merge branch 'dev' into feature-permissions 2023-01-01 17:51:41 -08:00
Michael Shamoon
d71d388c08 Merge branch 'dev' into feature-permissions 2022-12-29 20:12:42 -08:00
Michael Shamoon
e2093436ac lint for eslint 2022-12-17 21:49:08 -08:00
Michael Shamoon
b7e2013589 visually disable edit fields for permissions 2022-12-17 21:49:07 -08:00
Michael Shamoon
f31cee75f3 Merge branch 'dev' into feature-permissions 2022-12-17 20:05:12 -08:00
Michael Shamoon
ec27f3c053 move permissions input components 2022-12-14 00:47:54 -08:00
Michael Shamoon
737f00df3a Fix bulk setting null owner / permissions 2022-12-14 00:47:54 -08:00
Michael Shamoon
e6804dad2f consumed via mail should default to owner 2022-12-13 22:22:12 -08:00
Michael Shamoon
1875e9852e Resolve migration conflict 2022-12-13 07:00:52 -08:00
Michael Shamoon
f021e7fcc3 Merge branch 'dev' into feature-permissions 2022-12-13 06:57:33 -08:00
Michael Shamoon
4cf9ed9d26 Support owner and object permissions for advanced queries 2022-12-12 22:40:31 -08:00
Michael Shamoon
f8b77d7ef7 fix inherited permissions not visually showing as checked 2022-12-12 22:40:31 -08:00
Michael Shamoon
31850c3351 fix empty set permissions 2022-12-12 13:37:59 -08:00
Michael Shamoon
446842ecfc Document uploads should be owned by user 2022-12-12 13:24:59 -08:00
Michael Shamoon
8159b7574c Use accordion for permissions in object edit dialogs 2022-12-10 17:02:02 -08:00
Michael Shamoon
7050f29cff Forgot to include ObjectOwnedOrGrandtedPermissionsFilter on documents 2022-12-10 15:40:34 -08:00
Michael Shamoon
2f32565476 fix user / group editing 2022-12-10 15:36:07 -08:00
Michael Shamoon
ceeb2da3fe Merge branch 'dev' into feature-permissions 2022-12-09 17:54:14 -08:00
Michael Shamoon
6dc5c1de32 Support bulk edit owner 2022-12-09 17:51:01 -08:00
Michael Shamoon
a5ab6f2558 Add ability to set owner per object 2022-12-09 15:54:30 -08:00
Michael Shamoon
f846c2934c fix missing perms on Tags 2022-12-09 09:29:31 -08:00
Michael Shamoon
1adb5e724d fix object creation, user serialization, user creation 2022-12-09 04:59:15 -08:00
Michael Shamoon
8fad13b500 Merge branch 'dev' into feature-permissions 2022-12-09 03:31:26 -08:00
Michael Shamoon
6b2ee0e301 Merge branch 'dev' into feature-permissions 2022-12-08 12:53:27 -08:00
Michael Shamoon
7a241950d4 disable instead of hide doc edit buttons 2022-12-08 11:19:52 -08:00
Michael Shamoon
c1a1f6d74e Return all perms for superusers 2022-12-08 11:10:13 -08:00
Michael Shamoon
b99422da12 Address CodeQL 2022-12-08 09:31:00 -08:00
Michael Shamoon
2ec695fba7 remove dupe mail tab from settings 2022-12-08 02:39:33 -08:00
Michael Shamoon
109c07b23b Merge branch 'dev' into feature-permissions 2022-12-08 02:24:17 -08:00
Michael Shamoon
bf34c955ff Bulk editor enabling/disabling by permissions 2022-12-08 02:22:58 -08:00
Michael Shamoon
6ece5240a5 Bulk edit permissions 2022-12-08 02:03:50 -08:00
Michael Shamoon
211fbf0cf6 Refactor permissions API endpoints, UI group permissions 2022-12-08 00:05:16 -08:00
Michael Shamoon
f2d635671d Management lists edit / delete button disabling by permissions 2022-12-07 17:49:02 -08:00
Michael Shamoon
8b204cac99 disable document form components when no object permissions 2022-12-07 15:46:52 -08:00
Michael Shamoon
d15c701510 Remove display_name property 2022-12-07 14:59:27 -08:00
Michael Shamoon
c73688d167 add share to c/dt/t/sp, refactor share input, ifOwner directive 2022-12-07 14:55:40 -08:00
Michael Shamoon
32da039d5f fix tests for auth 2022-12-07 08:04:51 -08:00
Michael Shamoon
79da613cb6 Unify API perm endpoint to set_permissions, initial frontend support for doc sharing 2022-12-07 00:49:26 -08:00
Michael Shamoon
2973e4672a fix python tests for user object perms 2022-12-06 22:05:24 -08:00
Michael Shamoon
18e0012a59 API object permissions retrieval, grant and revoke 2022-12-06 22:05:24 -08:00
Michael Shamoon
2554ced198 Object creation with owner 2022-12-05 23:41:17 -08:00
Michael Shamoon
fad13c148e Object-level permissions + filtering 2022-12-05 22:56:03 -08:00
Michael Shamoon
dbaa606a9f add django-guardian, djangorestframework-guardian 2022-12-05 21:02:56 -08:00
Michael Shamoon
c0bccc6a95 Merge branch 'dev' into feature-global-ui-permissions 2022-12-05 15:56:32 -08:00
Michael Shamoon
b1a4eec7be Change toggle all, fix multiple group inheritance, fix select dark mode display 2022-12-05 15:51:53 -08:00
Michael Shamoon
bb8a0d26e2 Fix superuser initial disable individual perms, permissions select setup 2022-12-05 13:23:08 -08:00
Michael Shamoon
629a5dd61e Fix some merge errors, integrate permissions for frontend mail 2022-12-05 12:28:44 -08:00
Michael Shamoon
b21970fd53 Merge branch 'dev'
commit fb9d3f736b
Merge: 4d4d5453 049dc179
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sun Dec 4 16:47:58 2022 -0800

    Merge pull request #2000 from paperless-ngx/feature-frontend-paperless-mail

    Feature: frontend paperless mail

commit 4d4d545343
Merge: 2704bcb9 4b31e5d0
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Sun Dec 4 16:34:41 2022 -0800

    Merge pull request #848 from p-h-a-i-l/feature-consume-eml

    Feature ability to consume mails and eml files

commit 049dc17902
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Dec 4 16:33:07 2022 -0800

    Moves where the mail views live and puts the ordering on those

commit 4b31e5d0b4
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Dec 4 14:00:59 2022 -0800

    Fixes my broken formatting

commit 8076ebd78c
Merge: fe2db4db 2704bcb9
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Dec 4 13:55:46 2022 -0800

    Merge remote-tracking branch 'upstream/dev' into feature-consume-eml

commit 2704bcb979
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Dec 4 13:06:18 2022 -0800

    Resets to -dev versioning

commit 59f6074093
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Dec 4 12:58:03 2022 -0800

    Bumps version to 1.10.2

commit b1da7f3491
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Dec 4 12:57:19 2022 -0800

    Probably fixes the changelog step not working

commit adde88e7b9
Merge: a8f3c4be 8e876ef2
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Dec 4 12:55:55 2022 -0800

    Merge branch 'dev'

commit 8e876ef2d1
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Dec 4 10:20:48 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit 2ea0f83a91
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 05:12:02 2022 -0800

    New translations messages.xlf (Italian)
    [ci skip]

commit 05d8ea5a9d
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:09:05 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit 967248233f
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:09:04 2022 -0800

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

commit b4c4b9fb6a
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:09:03 2022 -0800

    New translations messages.xlf (Spanish)
    [ci skip]

commit adb6483abc
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:09:01 2022 -0800

    New translations messages.xlf (Arabic)
    [ci skip]

commit 908db55bb7
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:09:00 2022 -0800

    New translations messages.xlf (Belarusian)
    [ci skip]

commit 610f20de28
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:59 2022 -0800

    New translations messages.xlf (Czech)
    [ci skip]

commit b2513a5cde
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:57 2022 -0800

    New translations messages.xlf (Danish)
    [ci skip]

commit bfa1c13d01
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:56 2022 -0800

    New translations messages.xlf (Finnish)
    [ci skip]

commit 12aaff431f
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:55 2022 -0800

    New translations messages.xlf (Hebrew)
    [ci skip]

commit 547e5ea55e
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:54 2022 -0800

    New translations messages.xlf (Italian)
    [ci skip]

commit c301127096
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:52 2022 -0800

    New translations messages.xlf (Dutch)
    [ci skip]

commit 19147855e7
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:51 2022 -0800

    New translations messages.xlf (Romanian)
    [ci skip]

commit 4e7c7ea1d6
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:49 2022 -0800

    New translations messages.xlf (Norwegian)
    [ci skip]

commit fcf8a49160
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:48 2022 -0800

    New translations messages.xlf (Portuguese)
    [ci skip]

commit c6d658a954
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:47 2022 -0800

    New translations messages.xlf (Russian)
    [ci skip]

commit a78cd6526c
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:45 2022 -0800

    New translations messages.xlf (Slovenian)
    [ci skip]

commit bf895b54f4
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:44 2022 -0800

    New translations messages.xlf (Swedish)
    [ci skip]

commit e5f84ef583
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:43 2022 -0800

    New translations messages.xlf (Turkish)
    [ci skip]

commit 8c690a9a51
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:41 2022 -0800

    New translations messages.xlf (Chinese Simplified)
    [ci skip]

commit 56526b970a
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:40 2022 -0800

    New translations messages.xlf (Portuguese, Brazilian)
    [ci skip]

commit 94fbf92916
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:38 2022 -0800

    New translations messages.xlf (Croatian)
    [ci skip]

commit 37f5e46d09
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:37 2022 -0800

    New translations messages.xlf (Luxembourgish)
    [ci skip]

commit 38be817637
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:36 2022 -0800

    New translations messages.xlf (Polish)
    [ci skip]

commit 17303f41da
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Dec 3 02:08:34 2022 -0800

    New translations messages.xlf (German)
    [ci skip]

commit 55ef0d4a1b
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Dec 4 08:44:35 2022 -0800

    Fixes language code checks around two part languages

commit a8f3c4be54
Merge: fa62ae82 1b9de2be
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 18:47:09 2022 -0800

    Merge pull request #1947 from alexander-bauer/helm

    Take ownership of k8s-at-home Helm chart,

commit 1b9de2be5a
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 18:46:19 2022 -0800

    Use checkout v3

commit 0e8265f1ae
Merge: ea38eb01 5b45a140
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 18:44:28 2022 -0800

    Merge pull request #2109 from paperless-ngx/fix/redis-socket-parsing

    Bugfix: Redis socket compatibility didn't handle URLs with ports

commit 5b45a140b9
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sat Dec 3 18:30:21 2022 -0800

    Fixes issue when the Redis URL also specifies a port

commit 72fb9a475d
Author: Alexander Bauer <sasha@linux.com>
Date:   Thu Nov 10 02:24:04 2022 +0000

    Ignore end-of-lines on generated Chart README

commit bf97f5807f
Author: Alexander Bauer <sasha@linux.com>
Date:   Thu Nov 10 02:21:29 2022 +0000

    Ignore non-yaml Helm chart template

commit a707818b4d
Author: Alexander Bauer <sasha@linux.com>
Date:   Thu Nov 10 01:54:35 2022 +0000

    Change Helm chart releaser to use version tags only

commit fb46c1b96a
Author: Alexander Bauer <sasha@linux.com>
Date:   Thu Nov 10 01:52:02 2022 +0000

    Ignore generated Helm chart README from prettier

commit 3226d8b25b
Author: Alexander Bauer <sasha@linux.com>
Date:   Tue Nov 8 00:46:27 2022 +0000

    fixup! Add mostly-unchanged Helm chart from k8s-at-home

commit 5c4363cbea
Author: Alexander Bauer <sasha@linux.com>
Date:   Tue Nov 8 00:24:04 2022 +0000

    Add mostly-unchanged Helm chart from k8s-at-home

    - Add the chart from k8s-at-home with some modifications
    - Add the Apache 2.0 license to the new charts/paperless-ngx
      subdirectory, the license under which the chart was distributed by
      k8s-at-home. I believe the chart will have to maintain this license.

    - Update the maintainers section and contact information to point to
      Paperless-ngx.
    - Regenerate the README (using helm-docs)

    - Add a GitHub actions configuration to publish the chart using GitHub
      pages. This makes the GitHub Pages page rendered by this repository
      usable as a Helm repository, without affecting potential future uses
      of the Pages site.

    These are in response to discussion #1790.

commit fa62ae820b
Merge: bcc029a2 17891baf
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 14:19:36 2022 -0800

    Merge pull request #2106 from tooomm/docs/edit

    Docs: Some more small MkDocs updates

commit 17891bafaf
Author: tooomm <tooomm@users.noreply.github.com>
Date:   Sat Dec 3 20:02:40 2022 +0100

    lint

commit 15fdadadef
Author: tooomm <tooomm@users.noreply.github.com>
Date:   Sat Dec 3 19:36:49 2022 +0100

    open demo in new page

commit ce9f604d81
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 09:29:34 2022 -0800

    Explicit default ordering for rule / account views

commit 4f876db5d1
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Nov 28 21:38:52 2022 -0800

    prevent loss of unsaved changes to settings on tab nav

commit 5e5f56dc67
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Nov 28 20:39:03 2022 -0800

    Re-org where some of the new classes are found

commit 93fab8bb95
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Nov 28 12:53:20 2022 -0800

    Apply code suggestions from @stumpylog

commit 35ca2195fe
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Nov 28 15:51:39 2022 -0800

    frontend mail rule validation

    Display non-field validation errors, hide action param field if not needed

commit 7ace66d7fd
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Nov 28 13:58:37 2022 -0800

    fix edit dialog getters

commit 4f9a31244b
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Nov 18 20:23:40 2022 -0800

    Add settings routing

commit 14cf4f7095
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Nov 18 19:38:49 2022 -0800

    Update frontend strings

commit 8bd7c27826
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Nov 18 17:11:15 2022 -0800

    Hide order parameter, fix imap port

commit 8c4f486fe9
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Nov 18 14:22:07 2022 -0800

    API mail rule & account tests

    and fix use of assign_tags

commit 2849414445
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Nov 18 14:21:31 2022 -0800

    one-way imap password setting via API, ObfuscatedPasswordField

commit ea1ea0816f
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Nov 18 14:10:17 2022 -0800

    Fix mail account / rule delete

commit 52d3a8703c
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Nov 12 15:14:58 2022 -0800

    Dynamically load mail rules / accounts settings

commit 4cb4d6adcd
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Nov 12 15:15:59 2022 -0800

    update settings tests to not wait on data which is now on-demand

commit 24444237f2
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Nov 12 14:46:57 2022 -0800

    dynamic loading of settings tab contents

commit 40c8629aef
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Nov 10 21:04:29 2022 -0800

    Update welcome tour, move admin button

commit 98cdf614a5
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Wed Nov 9 19:59:35 2022 -0800

    Mail form tweaks

    Include add button

    Include add button

commit 2eb2d99a91
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Wed Nov 9 03:43:57 2022 -0800

    Update frontend fixtures & tests for compatibility

commit 18ad9bcbf2
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 8 12:18:47 2022 -0800

    Working mail rule & account edit

commit 997bff4917
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Wed Nov 9 02:40:45 2022 -0800

    Update deprecated edit-dialog rxjs

commit 78f9a80895
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 8 12:09:16 2022 -0800

    mail account + rule deletion

commit 9231df7a4a
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 8 11:50:57 2022 -0800

    Mail rule edit dialog

commit 6f25917c86
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 8 11:11:35 2022 -0800

    Mail account edit dialog

commit c41d1a78a8
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 8 10:53:41 2022 -0800

    remove unused toastService from edit dialogs and add confirmation

commit c3331086d5
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 8 03:39:54 2022 -0800

    Basic data retrieval

commit 6bd9ccd8f6
Author: tooomm <tooomm@users.noreply.github.com>
Date:   Sat Dec 3 18:30:02 2022 +0100

    update default edit path

commit 68c7cecb07
Author: tooomm <tooomm@users.noreply.github.com>
Date:   Sat Dec 3 18:29:14 2022 +0100

    add mkdocs site to gitignore

commit bcc029a2c7
Merge: 9d418055 1727eb00
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 09:00:02 2022 -0800

    Merge pull request #2104 from paperless-ngx/docs-cleanup

    Chore: Cleans up documentation links

commit ea38eb01b2
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Fri Dec 2 13:54:15 2022 -0800

    Adds support for database number specification

commit 01d070b882
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Fri Dec 2 09:34:59 2022 -0800

    Adds a layer to translate between differing formats of socket based Redis URLs

commit 1727eb00cc
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Fri Dec 2 19:34:43 2022 -0800

    Cleans up a number of internal links

commit 9d4180553c
Merge: 7c614264 8049af4b
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 07:58:12 2022 -0800

    Merge pull request #2102 from tooomm/patch-1

    Fix doc links in contributing

commit 8049af4b22
Author: tooomm <tooomm@users.noreply.github.com>
Date:   Sat Dec 3 14:38:55 2022 +0100

    Fix doc links in contributing

commit 7c6142643d
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 02:08:51 2022 -0800

    Update more docs references

commit 2e8706f4e2
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 02:05:49 2022 -0800

    Update frontend translation strings

commit d39d32d555
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 02:04:30 2022 -0800

    Fix docs references

commit 6f52945449
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 01:47:04 2022 -0800

    docs index formatting error

commit 37025297b5
Merge: aa023ea2 dc9e9e3b
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 01:33:31 2022 -0800

    Merge pull request #2095 from paperless-ngx/update-readme-doc-links

    Documentation: Update docs links and screenshot in readme, add favicon

commit aa023ea2e3
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Dec 3 01:30:07 2022 -0800

    correct docs deploy domain

commit 78bf0b63a5
Merge: 29391c1c a96ecd67
Author: Felix E <felix@eckhofer.com>
Date:   Sat Dec 3 09:10:20 2022 +0100

    Merge pull request #2087 from Ricks-ha/main

    Add examples to URL and TIME_ZONE

commit dc9e9e3b48
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Dec 2 20:06:51 2022 -0800

    add favicon

commit ab29c49b7a
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Dec 2 19:09:19 2022 -0800

    Update docs links and screenshot in readme

commit 1c0ac474b8
Merge: 25fb8d9c 29391c1c
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Fri Dec 2 19:05:28 2022 -0800

    Merge branch 'main' into dev

commit 29391c1c7b
Merge: 58a01a57 69383497
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Dec 2 15:22:39 2022 -0800

    Merge pull request #2067 from paperless-ngx/material-docs

    [WIP] Feature: Move docs to material-mkdocs

commit 693834971c
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 20:00:23 2022 -0800

    Add v1.10.1 changelog

commit 97376d4b72
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Dec 2 09:09:29 2022 -0800

    update ci for documentation build vs deploy

commit 3ee1d2a9a9
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 29 21:20:45 2022 -0800

    Add changes from #2069

commit 605f885e19
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 29 12:49:23 2022 -0800

    Move docs to material-mkdocs

commit 25fb8d9c3b
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Dec 2 08:30:42 2022 -0800

    Update dev version string

commit a96ecd673b
Author: Ricks-ha <ricks@ricksha.eu>
Date:   Fri Dec 2 13:27:57 2022 +0100

    Add examples to URL and TIME_ZONE

commit 58a01a57ee
Merge: a96f79f6 c18fc03e
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Dec 2 03:36:55 2022 -0800

    Merge pull request #2082 from paperless-ngx/v1.10.1-changelog

    Chore: Add v1.10.1 changelong

commit c18fc03ef3
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 20:00:23 2022 -0800

    Add v1.10.1 changelong

commit a96f79f6a3
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 18:54:00 2022 -0800

    Bump version to 1.10.1

commit d6f1d004a3
Merge: 88cf6ef8 da72d357
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 18:52:35 2022 -0800

    Merge branch 'dev'

commit da72d3571b
Merge: 8241da0e 86592928
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 18:52:06 2022 -0800

    Merge pull request #2050 from paperless-ngx/l10n_dev

    New Crowdin updates

commit 8241da0eb3
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 17:01:22 2022 -0800

    fix broken npm package-lock

commit 51562667bf
Merge: 1aee2988 97eeae65
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 16:40:07 2022 -0800

    Merge pull request #2076 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/tslib-2.4.1

    Bump tslib from 2.4.0 to 2.4.1 in /src-ui

commit 97eeae65a3
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Fri Dec 2 00:39:26 2022 +0000

    Bump tslib from 2.4.0 to 2.4.1 in /src-ui

    Bumps [tslib](https://github.com/Microsoft/tslib) from 2.4.0 to 2.4.1.
    - [Release notes](https://github.com/Microsoft/tslib/releases)
    - [Commits](https://github.com/Microsoft/tslib/compare/2.4.0...2.4.1)

    ---
    updated-dependencies:
    - dependency-name: tslib
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

commit 1aee2988f7
Merge: a63a8dd4 6f0077ef
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 16:39:24 2022 -0800

    Merge pull request #2079 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/angular-builders/jest-14.1.0

    Bump @angular-builders/jest from 14.0.1 to 14.1.0 in /src-ui

commit a63a8dd488
Merge: 06a9df6d 39be68a1
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 16:38:38 2022 -0800

    Merge pull request #2078 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/jest-preset-angular-12.2.3

    Bump jest-preset-angular from 12.2.2 to 12.2.3 in /src-ui

commit 06a9df6dbd
Merge: 49933bb5 7d7d9630
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 16:37:25 2022 -0800

    Merge pull request #2080 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/ngx-file-drop-14.0.2

    Bump ngx-file-drop from 14.0.1 to 14.0.2 in /src-ui

commit 49933bb5a8
Merge: 02c782a1 ac69babf
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 16:18:07 2022 -0800

    Merge pull request #2077 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/ngneat/dirty-check-forms-3.0.3

    Bump @ngneat/dirty-check-forms from 3.0.2 to 3.0.3 in /src-ui

commit 7d7d9630c1
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Thu Dec 1 20:03:32 2022 +0000

    Bump ngx-file-drop from 14.0.1 to 14.0.2 in /src-ui

    Bumps [ngx-file-drop](https://github.com/georgipeltekov/ngx-file-drop) from 14.0.1 to 14.0.2.
    - [Release notes](https://github.com/georgipeltekov/ngx-file-drop/releases)
    - [Changelog](https://github.com/georgipeltekov/ngx-file-drop/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/georgipeltekov/ngx-file-drop/compare/v14.0.1...v14.0.2)

    ---
    updated-dependencies:
    - dependency-name: ngx-file-drop
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

commit 6f0077efac
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Thu Dec 1 20:03:05 2022 +0000

    Bump @angular-builders/jest from 14.0.1 to 14.1.0 in /src-ui

    Bumps [@angular-builders/jest](https://github.com/just-jeb/angular-builders/tree/HEAD/packages/jest) from 14.0.1 to 14.1.0.
    - [Release notes](https://github.com/just-jeb/angular-builders/releases)
    - [Changelog](https://github.com/just-jeb/angular-builders/blob/master/packages/jest/CHANGELOG.md)
    - [Commits](https://github.com/just-jeb/angular-builders/commits/@angular-builders/jest@14.1.0/packages/jest)

    ---
    updated-dependencies:
    - dependency-name: "@angular-builders/jest"
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

commit 39be68a1a4
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Thu Dec 1 20:02:39 2022 +0000

    Bump jest-preset-angular from 12.2.2 to 12.2.3 in /src-ui

    Bumps [jest-preset-angular](https://github.com/thymikee/jest-preset-angular) from 12.2.2 to 12.2.3.
    - [Release notes](https://github.com/thymikee/jest-preset-angular/releases)
    - [Changelog](https://github.com/thymikee/jest-preset-angular/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/thymikee/jest-preset-angular/compare/v12.2.2...v12.2.3)

    ---
    updated-dependencies:
    - dependency-name: jest-preset-angular
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

commit ac69babfce
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Thu Dec 1 20:02:11 2022 +0000

    Bump @ngneat/dirty-check-forms from 3.0.2 to 3.0.3 in /src-ui

    Bumps [@ngneat/dirty-check-forms](https://github.com/ngneat/dirty-check-forms) from 3.0.2 to 3.0.3.
    - [Release notes](https://github.com/ngneat/dirty-check-forms/releases)
    - [Changelog](https://github.com/ngneat/dirty-check-forms/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/ngneat/dirty-check-forms/compare/v3.0.2...v3.0.3)

    ---
    updated-dependencies:
    - dependency-name: "@ngneat/dirty-check-forms"
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

commit 02c782a127
Merge: 4e90fda8 9b602a4b
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Dec 1 08:19:59 2022 -0800

    Merge pull request #2073 from paperless-ngx/fix-frontend-tasks-display

    Fix: frontend tasks display in 1.10.0

commit 4e90fda80f
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Tue Nov 29 20:06:56 2022 -0800

    Expands documentation around the permissions of the custom scripts and the folder

commit 88e3e556a1
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Tue Nov 29 20:05:08 2022 -0800

    Fixes the custom scripts not running as root

commit 88cf6ef843
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Wed Nov 30 15:14:21 2022 -0800

    add demo badge

commit 9b602a4bf0
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Wed Nov 30 13:55:51 2022 -0800

    Fix frontend tasks display

commit fe2db4dbf7
Author: phail <phail@hacknology.de>
Date:   Wed Nov 30 10:16:39 2022 +0100

    adapt compose file for eml parsing

commit 47c88a6bdd
Merge: 4aa31859 a3bc3b78
Author: phail <phail@hacknology.de>
Date:   Wed Nov 30 10:10:57 2022 +0100

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit a3bc3b78d5
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Tue Nov 29 14:34:12 2022 -0800

    Also display the container logs

commit fed7d3e993
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Tue Nov 29 13:59:48 2022 -0800

    Use docker compose to start and stop containers which match directly to our command overrides

commit 3a74f24e49
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Tue Nov 29 12:44:53 2022 -0800

    Adds libatomic1 for supporting armv7 better

commit 52afab39cf
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Tue Nov 29 12:16:51 2022 -0800

    Organizes the system packages a little bit more

commit 8659292852
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Tue Nov 29 00:29:45 2022 -0800

    New translations django.po (Norwegian)
    [ci skip]

commit ce73f159fd
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Mon Nov 28 14:13:54 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit 71382e9c62
Merge: 5d3a6e23 a1a802fc
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Nov 28 14:05:57 2022 -0800

    Merge pull request #2062 from paperless-ngx/fix/2053-long-names-too-quiet

    Bugfix: Don't silence an exception when trying to handle file naming

commit a1a802fc92
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Mon Nov 28 13:44:17 2022 -0800

    Don't silence an exception when trying to handle file naming

commit 4200fc610d
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Mon Nov 28 13:17:22 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit 32d212cd9f
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Mon Nov 28 11:17:07 2022 -0800

    New translations messages.xlf (German)
    [ci skip]

commit 5d3a6e230d
Merge: b33fcc11 f0497e77
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Nov 28 11:04:44 2022 -0800

    Merge pull request #2057 from paperless-ngx/fix/2044-lang-code-diffs

    Bugfix: Some tesseract languages aren't detected as installed.

commit b33fcc117e
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Mon Nov 28 09:25:03 2022 -0800

    Transition to a maintained upload release assert

commit e96d65f945
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Mon Nov 14 15:38:35 2022 -0800

    Allows parsing of WebP format images

commit cfeed0ce6e
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Mon Nov 28 08:30:32 2022 -0800

    New translations django.po (Polish)
    [ci skip]

commit b89ecf7d77
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Mon Nov 28 05:28:39 2022 -0800

    New translations messages.xlf (Luxembourgish)
    [ci skip]

commit 5ca25d44ba
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Mon Nov 28 04:27:31 2022 -0800

    New translations messages.xlf (Luxembourgish)
    [ci skip]

commit 1e11c12d96
Merge: e74d7dad 3e22e8e0
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sun Nov 27 21:16:50 2022 -0800

    Merge branch 'main' into dev

commit 3e22e8e0b9
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 27 19:22:59 2022 -0800

    prepends the latest changelog

commit dba45f93a4
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 27 19:22:03 2022 -0800

    Fixes the pre-commit command

commit 18f3f44ae9
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:25 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit 85a6a271dc
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:23 2022 -0800

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

commit abb515d4ea
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:22 2022 -0800

    New translations messages.xlf (Spanish)
    [ci skip]

commit 309d1f2b67
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:21 2022 -0800

    New translations messages.xlf (Arabic)
    [ci skip]

commit fa2f09bc4b
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:19 2022 -0800

    New translations messages.xlf (Belarusian)
    [ci skip]

commit c51590cd12
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:18 2022 -0800

    New translations messages.xlf (Czech)
    [ci skip]

commit 8e01406acf
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:17 2022 -0800

    New translations messages.xlf (Danish)
    [ci skip]

commit 7cce2f0fe6
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:16 2022 -0800

    New translations messages.xlf (Finnish)
    [ci skip]

commit 95091c2f39
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:14 2022 -0800

    New translations messages.xlf (Hebrew)
    [ci skip]

commit 4a0aa12bd9
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:13 2022 -0800

    New translations messages.xlf (Italian)
    [ci skip]

commit 9a0329746a
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:11 2022 -0800

    New translations messages.xlf (Dutch)
    [ci skip]

commit 8392a6fd4a
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:10 2022 -0800

    New translations messages.xlf (Romanian)
    [ci skip]

commit 8fa18bb8a6
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:09 2022 -0800

    New translations messages.xlf (Norwegian)
    [ci skip]

commit 0095b593fb
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:08 2022 -0800

    New translations messages.xlf (Portuguese)
    [ci skip]

commit b1e5135e21
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:05 2022 -0800

    New translations messages.xlf (Russian)
    [ci skip]

commit e88755e7ac
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:04 2022 -0800

    New translations messages.xlf (Slovenian)
    [ci skip]

commit c582947291
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:02 2022 -0800

    New translations messages.xlf (Swedish)
    [ci skip]

commit 98fe3a2cb7
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:58:01 2022 -0800

    New translations messages.xlf (Turkish)
    [ci skip]

commit 61647606fa
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:57:59 2022 -0800

    New translations messages.xlf (Chinese Simplified)
    [ci skip]

commit 95a1e5c645
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:57:58 2022 -0800

    New translations messages.xlf (Portuguese, Brazilian)
    [ci skip]

commit 8ead77f128
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:57:57 2022 -0800

    New translations messages.xlf (Croatian)
    [ci skip]

commit b9e9e82f33
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:57:55 2022 -0800

    New translations messages.xlf (Luxembourgish)
    [ci skip]

commit 487fd3a5dd
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:57:54 2022 -0800

    New translations messages.xlf (Polish)
    [ci skip]

commit 657786a2fe
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sun Nov 27 17:57:52 2022 -0800

    New translations messages.xlf (German)
    [ci skip]

commit e74d7dadfb
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 27 17:43:46 2022 -0800

    Adds the -dev back to the UI version

commit a2937cd54d
Merge: 9b01aa92 7b3ce628
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 27 17:42:41 2022 -0800

    Merge branch 'main' into dev

commit 7b3ce6289f
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 27 17:21:12 2022 -0800

    Bumps version number to 1.10.0

commit a16e8324be
Merge: 34a0111f 39de531d
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 27 17:18:08 2022 -0800

    Merge pull request #1960 from paperless-ngx/beta

    [Beta] Paperless-ngx v1.10.0 Release Candidate

commit 39de531df5
Merge: 4764d4fd c9d6c208
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sun Nov 27 14:47:14 2022 -0800

    Merge pull request #2041 from paperless-ngx/l10n_dev

    New Crowdin updates

commit 4764d4fd2b
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Nov 26 12:28:51 2022 -0800

    New translations django.po (German)
    [ci skip]

commit e147d4571f
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Nov 26 09:54:00 2022 -0800

    New translations django.po (German)
    [ci skip]

commit dc9aaa6472
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Tue Nov 22 15:21:31 2022 -0800

    New translations django.po (German)
    [ci skip]

commit 8a061c4ac2
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Tue Nov 22 15:21:30 2022 -0800

    New translations messages.xlf (German)
    [ci skip]

commit d051c5c282
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Nov 12 08:48:48 2022 -0800

    Remove ar-SA

commit 9e60810a8b
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Nov 12 08:33:08 2022 -0800

    New translations messages.xlf (Arabic)
    [ci skip]

commit 96ee7990b2
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Fri Nov 11 13:59:54 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit 224bfeb72e
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Fri Nov 11 13:04:01 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit f0497e7744
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 27 08:28:22 2022 -0800

    Fixes how a language code like chi-sim is treated in the checks

commit c9d6c208af
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Nov 26 12:28:51 2022 -0800

    New translations django.po (German)
    [ci skip]

commit 9f2b8b1734
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Nov 26 09:54:00 2022 -0800

    New translations django.po (German)
    [ci skip]

commit a04b9e3755
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Tue Nov 22 15:21:31 2022 -0800

    New translations django.po (German)
    [ci skip]

commit a81d4c5e9d
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Tue Nov 22 15:21:30 2022 -0800

    New translations messages.xlf (German)
    [ci skip]

commit 2140d42098
Merge: a5283525 2a5dc4de
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 22 14:35:34 2022 -0800

    Merge pull request #2025 from paperless-ngx/fix-redo-ocr-message

    Add info that re-do OCR doesnt automatically refresh content

commit 43325371fc
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Nov 12 08:48:48 2022 -0800

    Remove ar-SA

commit d10721089e
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Nov 12 08:33:08 2022 -0800

    New translations messages.xlf (Arabic)
    [ci skip]

commit f1a1a2da8b
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Fri Nov 11 13:59:54 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit 612e0a1163
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Fri Nov 11 13:04:01 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit 2a5dc4de38
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 22 14:16:04 2022 -0800

    Add info that re-do OCR doesnt automatically refresh content

commit a5283525bc
Merge: f0155565 de98d748
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Nov 22 13:53:08 2022 -0800

    Merge pull request #2023 from paperless-ngx/fix/2019-create-date

    Bugfix: Fix created_date being a string

commit de98d748a9
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Tue Nov 22 10:11:27 2022 -0800

    If override_date is provided, coerce it into a datetime

commit f015556562
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Mon Nov 21 14:56:14 2022 -0800

    Adds a test to cover this edge case

commit b897d6de2e
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Mon Nov 21 14:45:20 2022 -0800

    Don't use the sidecar file when redoing the OCR, it only contains new text

commit 54f20b381e
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Mon Nov 21 12:59:14 2022 -0800

    Documents some issues and the required manual fixes for MariaDB

commit c0d4248021
Merge: 27f7f0a9 870e295a
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Nov 21 22:19:02 2022 -0800

    Merge pull request #1973 from paperless-ngx/l10n_dev

    New Crowdin updates

commit 870e295aae
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Mon Nov 21 21:43:54 2022 -0800

    New translations messages.xlf (German)
    [ci skip]

commit 4aa318598f
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 23:26:20 2022 +0100

    add test comments

commit 00f39d8b58
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 22:49:42 2022 +0100

    add test comments

commit 0b1a16908f
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 20:33:07 2022 +0100

    Include .eml reference in docs

commit d9796e5003
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 20:24:36 2022 +0100

    change order of elements in parsed Texts

commit 3599bb52c0
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 20:12:41 2022 +0100

    minor test improvements

commit af8a6c3764
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 19:53:57 2022 +0100

    fix filenames

commit 6d37ebf79e
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 20 09:15:06 2022 -0800

    Fixes one more place which used manual size formatting

commit f6a70b85f4
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 20 09:13:08 2022 -0800

    Use Django templating engine

commit 538a4219bd
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 20 09:10:44 2022 -0800

    Fixes missing return

commit 85c41b79be
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Sun Nov 20 08:02:06 2022 -0800

    Adds the new packages without updating other dependencies

commit 25d014d8ef
Merge: 9ec89762 27f7f0a9
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sun Nov 20 07:48:55 2022 -0800

    Merge branch 'beta' into l10n_dev

commit 9b01aa9202
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Mon Nov 14 15:47:22 2022 -0800

    Fixes the link for flake8 to the new (?) GitHub repo

commit df101f5e7a
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 16:09:46 2022 +0100

    split handle_message function

commit 1fa735eb23
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 15:44:43 2022 +0100

    use imagehash instead of bitwise hashing

commit ebe21a0114
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 14:22:30 2022 +0100

    eml parsing requires tika

commit d132eba143
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 12:48:03 2022 +0100

    optimize regex

commit 073c3c8fed
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 12:36:49 2022 +0100

    use html.escape instead of some self build functions

commit e3c1bde793
Author: phail <phail@hacknology.de>
Date:   Sun Nov 20 12:06:35 2022 +0100

    remove log mocking, replace pytest raises, use humanfriendly

commit 27f7f0a941
Merge: 9f5fd6c3 914661fd
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Nov 17 14:31:46 2022 -0800

    Merge pull request #1998 from paperless-ngx/fix/1993-date-overflow

    Bugfix: Don't allow exceptions during date parsing to fail consume

commit 9f5fd6c3ba
Merge: 0ae82005 3dfeee93
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Nov 17 14:30:23 2022 -0800

    Merge pull request #1967 from paperless-ngx/feature-scripts-output

    Feature: Capture stdout & stderr of the pre/post consume scripts

commit 914661fdbb
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Thu Nov 17 13:37:37 2022 -0800

    Don't allow an exception when trying to parse a date cause complete failure

commit 0ae8200593
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Mon Nov 14 15:47:22 2022 -0800

    Fixes the link for flake8 to the new (?) GitHub repo

commit b68906b14e
Author: phail <phail@hacknology.de>
Date:   Sun Nov 13 22:49:52 2022 +0100

    merge pipfile

commit 681eecc46e
Merge: 1578e8de d4712234
Author: phail <phail@hacknology.de>
Date:   Sun Nov 13 22:43:55 2022 +0100

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit 1578e8de2d
Author: phail <phail@hacknology.de>
Date:   Sun Nov 13 22:33:26 2022 +0100

    fix live tests

commit 023c931401
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sun Nov 13 07:11:45 2022 -0800

    Fix top search not working due to missing button type

commit 9ec89762a3
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Nov 12 09:31:54 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit fa47595ac8
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Nov 12 08:58:01 2022 -0800

    remove ar_SA

    [ci skip]

commit 79f5019b40
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Sat Nov 12 08:53:52 2022 -0800

    New Crowdin updates (#1971)

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

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

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

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

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

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

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

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

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

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

    * New translations messages.xlf (Portuguese, Brazilian)
    [ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    * Remove ar-SA

    * remote ar other than ar-ar

    Co-authored-by: Michael Shamoon <4887959+shamoon@users.noreply.github.com>

commit 756ce2f9d8
Merge: 50a211f3 d4712234
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Nov 12 08:33:43 2022 -0800

    Merge branch 'dev' into beta

commit d47122340a
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sat Nov 12 08:31:25 2022 -0800

    Add translation strings for welcome tour buttons

commit b01cbc9aa0
Author: phail <phail@hacknology.de>
Date:   Sat Nov 12 15:48:30 2022 +0100

    add conditions to unittests

commit 3dfeee9332
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Fri Nov 11 10:09:56 2022 -0800

    Don't do decoding work if not needed

commit 057f6016cc
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Fri Nov 11 08:58:49 2022 -0800

    Adds further testing to cover scripts with non-zero exit codes

commit c4965580de
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Thu Nov 10 17:40:36 2022 -0800

    Fixes stderr appearing to have content when it doesn't

commit 9a47963fd5
Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
Date:   Wed Nov 9 20:11:36 2022 -0800

    Captures the stdout and stderr of the pre/post scripts into the log

commit 50a211f367
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Thu Nov 10 17:25:39 2022 -0800

    Fixes an issue with the install of languages and read-only variable

commit 5f278d7fbb
Merge: e5106bdc a17d2519
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Wed Nov 9 21:37:29 2022 -0800

    Merge pull request #1956 from paperless-ngx/l10n_dev

    New Crowdin updates

commit a17d251913
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:37 2022 -0800

    New translations django.po (Serbian (Latin))
    [ci skip]

commit 1cbf088656
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:36 2022 -0800

    New translations messages.xlf (Serbian (Latin))
    [ci skip]

commit d3254d6bcf
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:35 2022 -0800

    New translations messages.xlf (Luxembourgish)
    [ci skip]

commit 1543729c7b
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:34 2022 -0800

    New translations messages.xlf (Croatian)
    [ci skip]

commit ef2a96c34b
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:32 2022 -0800

    New translations messages.xlf (Portuguese, Brazilian)
    [ci skip]

commit 656b1e150f
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:31 2022 -0800

    New translations messages.xlf (Chinese Simplified)
    [ci skip]

commit e0f61003cf
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:30 2022 -0800

    New translations messages.xlf (Turkish)
    [ci skip]

commit 1ca98678cd
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:28 2022 -0800

    New translations messages.xlf (Swedish)
    [ci skip]

commit 9919cc1956
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:27 2022 -0800

    New translations messages.xlf (Slovenian)
    [ci skip]

commit d2096e3c05
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:26 2022 -0800

    New translations messages.xlf (Portuguese)
    [ci skip]

commit 5f2b508b7a
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:24 2022 -0800

    New translations messages.xlf (Polish)
    [ci skip]

commit 752d4f4249
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:23 2022 -0800

    New translations django.po (German)
    [ci skip]

commit 72e7d5150e
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:22 2022 -0800

    New translations messages.xlf (Norwegian)
    [ci skip]

commit 42a9e05a7f
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:21 2022 -0800

    New translations messages.xlf (Italian)
    [ci skip]

commit b4add2ed55
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:19 2022 -0800

    New translations messages.xlf (Hebrew)
    [ci skip]

commit ed7d9295bd
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:18 2022 -0800

    New translations messages.xlf (Finnish)
    [ci skip]

commit 5b7b1b2349
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:16 2022 -0800

    New translations messages.xlf (Danish)
    [ci skip]

commit d5c930acc9
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:15 2022 -0800

    New translations messages.xlf (Czech)
    [ci skip]

commit 4c93d6d7e6
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:14 2022 -0800

    New translations messages.xlf (Belarusian)
    [ci skip]

commit 066f3264fb
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:12 2022 -0800

    New translations messages.xlf (Spanish)
    [ci skip]

commit 88a803f949
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:11 2022 -0800

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

commit e69615dc06
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:10 2022 -0800

    New translations messages.xlf (Romanian)
    [ci skip]

commit a1e0840e24
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:08 2022 -0800

    New translations messages.xlf (Dutch)
    [ci skip]

commit d814353e83
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:07 2022 -0800

    New translations messages.xlf (German)
    [ci skip]

commit 06d7845eca
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:04 2022 -0800

    New translations django.po (Dutch)
    [ci skip]

commit ae8682c7a5
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:03 2022 -0800

    New translations django.po (Romanian)
    [ci skip]

commit c9c0b3d430
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:02 2022 -0800

    New translations django.po (Luxembourgish)
    [ci skip]

commit cc46fc7e4b
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:01 2022 -0800

    New translations django.po (Croatian)
    [ci skip]

commit d1b1ba21cd
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:12:00 2022 -0800

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

commit a009417a99
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:59 2022 -0800

    New translations django.po (Chinese Simplified)
    [ci skip]

commit 775da720ec
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:58 2022 -0800

    New translations django.po (Turkish)
    [ci skip]

commit aeae6ea0d3
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:57 2022 -0800

    New translations django.po (Swedish)
    [ci skip]

commit 0ae46d2269
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:56 2022 -0800

    New translations django.po (Slovenian)
    [ci skip]

commit 0e7f1ec0de
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:55 2022 -0800

    New translations django.po (Russian)
    [ci skip]

commit 13cd55b96f
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:53 2022 -0800

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

commit 9139e807ec
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:52 2022 -0800

    New translations messages.xlf (Arabic)
    [ci skip]

commit 53616f6625
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:51 2022 -0800

    New translations django.po (Polish)
    [ci skip]

commit 526fdf1153
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:50 2022 -0800

    New translations django.po (Italian)
    [ci skip]

commit fc4aceb0ee
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:49 2022 -0800

    New translations django.po (Hebrew)
    [ci skip]

commit 3d8421b718
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:48 2022 -0800

    New translations django.po (Finnish)
    [ci skip]

commit 6cebceda15
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:47 2022 -0800

    New translations django.po (Danish)
    [ci skip]

commit e1fd6bda19
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:46 2022 -0800

    New translations django.po (Czech)
    [ci skip]

commit fd34414b17
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:45 2022 -0800

    New translations django.po (Belarusian)
    [ci skip]

commit 3ce1886a54
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:44 2022 -0800

    New translations django.po (Arabic)
    [ci skip]

commit 8ed43779a8
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:43 2022 -0800

    New translations django.po (Spanish)
    [ci skip]

commit a7949b3e22
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:42 2022 -0800

    New translations django.po (French)
    [ci skip]

commit 19c293c3e6
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:41 2022 -0800

    New translations django.po (Norwegian)
    [ci skip]

commit ccb1ec4ff5
Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com>
Date:   Wed Nov 9 15:11:40 2022 -0800

    New translations messages.xlf (Russian)
    [ci skip]

commit e5106bdca0
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Wed Nov 9 14:00:09 2022 -0800

    Updates the version strings to 1.10.0

commit ba1366f49a
Merge: 34a0111f f3b3db30
Author: Trenton H <797416+stumpylog@users.noreply.github.com>
Date:   Wed Nov 9 13:51:10 2022 -0800

    Merge branch 'dev' into beta

commit acd3832417
Author: phail <phail@hacknology.de>
Date:   Thu Nov 3 21:08:15 2022 +0100

    merge Pipfile.lock

commit 82b2ba3cc2
Merge: 3de6e0bc 7e3e0a0f
Author: phail <phail@hacknology.de>
Date:   Thu Nov 3 21:00:01 2022 +0100

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit 3de6e0bcf1
Author: phail <phail@hacknology.de>
Date:   Thu Nov 3 00:58:36 2022 +0100

    put parser into setup
    make test using convert optional
    Gotenberg live testing

commit 34a0111ff5
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Oct 31 13:06:17 2022 -0700

    update logs section

commit b511b084d0
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Sun Oct 30 06:48:41 2022 -0700

    Update matrix url

    [ci skip]

commit 6df73ae940
Author: phail <phail@hacknology.de>
Date:   Sat Oct 29 23:20:35 2022 +0200

    gotenberg with modified cmd

commit 4a24ba51c5
Merge: 87472b31 d5fb98b7
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Oct 28 22:22:08 2022 -0700

    Merge pull request #1876 from astubenbord/main

    Added new application to list of affiliated projects

commit d5fb98b7c4
Author: Anton Stubenbord <79228196+astubenbord@users.noreply.github.com>
Date:   Fri Oct 28 11:07:42 2022 +0200

    Added new application to list of affiliated projects

commit 2204090151
Author: phail <phail@hacknology.de>
Date:   Thu Oct 27 23:53:47 2022 +0200

    fix string

commit 3c81a7468b
Author: phail <phail@hacknology.de>
Date:   Thu Oct 27 23:41:29 2022 +0200

    replace thumbnail creation with mock

commit 5ef86f9489
Merge: 90cb0836 9b82ab95
Author: phail <phail@hacknology.de>
Date:   Thu Oct 27 23:12:51 2022 +0200

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit 90cb0836bb
Author: phail <phail@hacknology.de>
Date:   Thu Oct 27 23:11:41 2022 +0200

    Downgrade pdf validation to text only

commit ef1d4264b5
Author: phail <phail@hacknology.de>
Date:   Thu Oct 27 00:27:15 2022 +0200

    improve test coverage a little

commit e1fa59122d
Merge: 5bf26369 3357fa19
Author: phail <phail@hacknology.de>
Date:   Wed Oct 26 20:59:49 2022 +0200

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit 5bf26369e2
Author: phail <phail@hacknology.de>
Date:   Tue Oct 25 21:17:40 2022 +0200

    remove erroring paramerter

commit 36239ba09f
Author: phail <phail@hacknology.de>
Date:   Mon Oct 24 22:15:33 2022 +0200

    rename help text

commit 318c1d2fbd
Merge: e7c40fc3 f8ce6285
Author: phail <phail@hacknology.de>
Date:   Mon Oct 24 21:12:35 2022 +0200

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit e7c40fc3dc
Author: phail <phail@hacknology.de>
Date:   Sun Oct 23 22:02:11 2022 +0200

    Update Pipfile

commit 0da0b1c062
Author: phail <phail@hacknology.de>
Date:   Sun Oct 23 21:39:15 2022 +0200

    update variable names

commit 08988e11f8
Merge: 30372b0e 8be6c707
Author: phail <phail@hacknology.de>
Date:   Sun Oct 23 20:37:22 2022 +0200

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit 30372b0e85
Author: phail <phail@hacknology.de>
Date:   Sun Oct 23 17:18:10 2022 +0200

    add tests for mail_to_html and generate_pdf_from_mail

commit 567e89d1c7
Author: phail <phail@hacknology.de>
Date:   Sat Oct 22 02:25:23 2022 +0200

    test for broken eml, add test_generate_pdf

commit f1f5227ccd
Author: phail <phail@hacknology.de>
Date:   Sat Oct 22 00:44:32 2022 +0200

    add unittest for external images

commit 09b5bd17f2
Author: phail <phail@hacknology.de>
Date:   Wed Oct 19 23:19:33 2022 +0200

    add unittest for generate_pdf_from_html

commit e384bd78c5
Author: phail <phail@hacknology.de>
Date:   Tue Oct 18 23:48:07 2022 +0200

    add unittest for transform_inline_html

commit fda844f64c
Author: phail <phail@hacknology.de>
Date:   Sat Oct 15 15:41:43 2022 +0200

    add unittest for parse

commit daf90399bd
Author: phail <phail@hacknology.de>
Date:   Sat Oct 15 13:13:29 2022 +0200

    Add unitest for tika_parse()

commit 3d37e49c1a
Author: phail <phail@hacknology.de>
Date:   Fri Oct 14 15:43:43 2022 +0200

    add 2 more tests

commit 261c6fb990
Author: phail <phail@hacknology.de>
Date:   Thu Oct 13 01:03:09 2022 +0200

    add unittest for get_thumbnail

commit 87472b31d2
Merge: 430c5c3b 1024d7e6
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Oct 11 19:59:46 2022 -0700

    Merge pull request #1780 from paperless-ngx/fix/issue-1647

    Documentation: Add note re MS exchange servers

commit 1024d7e6e2
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Oct 11 15:12:22 2022 -0700

    Add note re MS exchange servers

commit 430c5c3b87
Merge: 0b5c6d35 b7c33550
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Fri Oct 7 23:45:51 2022 -0700

    Merge pull request #1761 from paperless-ngx/docs/lsio-tweak

    Documentation: Tweak LinuxServer

commit b7c335507f
Author: Trenton Holmes <holmes.trenton@gmail.com>
Date:   Thu Oct 6 18:24:25 2022 -0700

    Fixes the LSIO migration setting for the media root

commit 0b5c6d3532
Merge: fdac108c 5fd39472
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Thu Oct 6 13:22:58 2022 -0700

    Merge pull request #1731 from paperless-ngx/fix/1624

    Documentation: Adds troubleshooting note about Kubernetes and ports

commit fdac108cab
Merge: 5639659b 821c14fb
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Mon Oct 3 17:07:06 2022 -0700

    Merge pull request #1733 from paperless-ngx/docs-lsio-migrate

    Documentation: LinuxServer.io Migration

commit 821c14fbce
Author: Trenton H <holmes.trenton@gmail.com>
Date:   Mon Oct 3 11:14:18 2022 -0700

    Corrects how the link to example compose files looks

commit 8c03d9c638
Author: Trenton H <holmes.trenton@gmail.com>
Date:   Mon Oct 3 11:11:51 2022 -0700

    Corrects a re-numbered step

commit 174a609449
Author: Trenton H <holmes.trenton@gmail.com>
Date:   Mon Oct 3 10:16:53 2022 -0700

    Adds a few steps for migration from the LinuxServer.io image

commit 5fd394726e
Author: Trenton H <holmes.trenton@gmail.com>
Date:   Mon Oct 3 09:01:07 2022 -0700

    Adds troubleshooting note for Kubernetes about needing to set the port again

commit 5639659b63
Merge: 807b7130 7ba9cdbe
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Wed Sep 28 09:48:20 2022 -0700

    Merge pull request #1683 from paperless-ngx/fix/issue-1660

    Mariadb compose files should use `PAPERLESS_DBPASS`

commit 7ba9cdbe23
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Wed Sep 28 09:07:30 2022 -0700

    Mariadb compose files should use `PAPERLESS_DBPASS`

commit 807b7130e5
Merge: 9d117ee1 e2d593c0
Author: shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Sep 27 16:50:23 2022 -0700

    Merge pull request #1671 from paperless-ngx/v1.9.2-changelog

    [Documentation] Add v1.9.2 changelog

commit e2d593c023
Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date:   Tue Sep 27 10:04:41 2022 -0700

    Fix formatting, add note about 1.9.1 version string

commit 7455963124
Author: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Date:   Tue Sep 27 17:01:37 2022 +0000

    Changelog  - GHA

commit cdd2b99b6b
Merge: d0a0ae91 72ce4405
Author: phail <phail@hacknology.de>
Date:   Mon Jul 11 23:58:21 2022 +0200

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit d0a0ae91c4
Merge: c04b9fd7 feaf2da8
Author: phail <phail@hacknology.de>
Date:   Fri May 20 19:29:52 2022 +0200

    Merge branch 'dev' into feature-consume-eml

commit c04b9fd7f6
Author: phail <phail@hacknology.de>
Date:   Thu May 19 22:51:17 2022 +0200

    switch to From: Header instead of date to compensate for older libmagic versions

commit 6809b15ce1
Author: phail <phail@hacknology.de>
Date:   Sat May 14 16:47:12 2022 +0200

    workaround for wrong mime detection of .eml files

commit c317eca1ca
Author: phail <phel@hacknology.de>
Date:   Thu May 5 00:20:32 2022 +0200

    add attachment size to pdf

commit 466afa8203
Author: phail <phel@hacknology.de>
Date:   Wed May 4 23:42:59 2022 +0200

    fix consumption of mails without html
    split pdf generation functions

commit c2e3dc76d9
Author: phail <phel@hacknology.de>
Date:   Tue May 3 23:21:33 2022 +0200

    add parsing of inline attachments
    remove insecure chromium option
    fix html parsing

commit 5a899664f8
Author: phail <phel@hacknology.de>
Date:   Tue May 3 18:02:08 2022 +0200

    remove .eml parser from tika

commit 990e905a04
Merge: 6b7155a8 98ebb095
Author: phail <phel@hacknology.de>
Date:   Tue May 3 17:42:56 2022 +0200

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit 6b7155a849
Author: phail <phel@hacknology.de>
Date:   Sat Apr 30 17:33:12 2022 +0200

    merge migrations

commit 47851ddd3f
Merge: 47189643 0f1e3164
Author: phail <phel@hacknology.de>
Date:   Fri Apr 29 23:52:56 2022 +0200

    Merge remote-tracking branch 'paperless/dev' into feature-consume-eml

commit 47189643ff
Author: phail <phel@hacknology.de>
Date:   Fri Apr 29 22:58:11 2022 +0200

    add eml parser to paperless_mail

commit c1efe11cf3
Author: phail <phel@hacknology.de>
Date:   Wed Apr 27 23:32:10 2022 +0200

    improve pdf generation

commit 0e40ef5f35
Author: phail <phel@hacknology.de>
Date:   Wed Apr 27 19:52:59 2022 +0200

    add css for pdf generation

commit c8081595c4
Author: phail <phel@hacknology.de>
Date:   Tue Apr 26 23:25:48 2022 +0200

    improve pdf generation

commit a2b5b3b253
Author: phail <phel@hacknology.de>
Date:   Tue Apr 26 23:12:36 2022 +0200

    moved files

commit 790bcf05ed
Author: phail <phel@hacknology.de>
Date:   Mon Apr 25 20:55:00 2022 +0200

    add prototype archive pdf

commit d8d2d53c59
Author: phail <phel@hacknology.de>
Date:   Tue Apr 19 20:14:31 2022 +0200

    fix Mail actions mixup

commit 027897ff03
Author: phail <phel@hacknology.de>
Date:   Tue Apr 19 00:39:00 2022 +0200

    work in progress Mail parsing

commit cca576f518
Author: phail <phel@hacknology.de>
Date:   Fri Apr 15 14:40:02 2022 +0200

    add feature to consume imap mail als .eml

commit 5fcf1b5434
Author: phail <phel@hacknology.de>
Date:   Thu Apr 14 00:19:30 2022 +0200

    remove uneeded print and fix merge fail

commit 942b5aa9df
Merge: c05b39a0 cc936160
Author: phail <phel@hacknology.de>
Date:   Wed Apr 13 23:55:38 2022 +0200

    Merge branch 'dev' into fix-mail-starttls

commit c05b39a056
Author: phail <phel@hacknology.de>
Date:   Wed Apr 13 23:37:21 2022 +0200

    fix unittest

commit 3c8196527f
Author: phail <phel@hacknology.de>
Date:   Sat Apr 9 13:07:14 2022 +0200

    adapt to starttls interface change in imap_tools
    pin imap-tools version to avoid breaking changes
    improve mail log

Update settings.component.ts

Update settings.component.ts
2022-12-05 01:35:42 -08:00
Michael Shamoon
4279ba13e9 Redirect and notify for perms guard, add frontend tests 2022-11-25 00:10:34 -08:00
Michael Shamoon
28d70438ec add api permissions test 2022-11-24 22:09:28 -08:00
Michael Shamoon
ca6454f9fd update frontend test fixture 2022-11-24 22:09:28 -08:00
Michael Shamoon
0ffc9955b2 Fix python tests with auth on API endpoints, add python tests for User/Group endpoints 2022-11-24 21:19:00 -08:00
Michael Shamoon
cf53d0866a Allow create / update password via UI 2022-11-23 00:35:17 -08:00
Trenton H
3f19c0ed03 Fixes the link for flake8 to the new (?) GitHub repo 2022-11-22 23:36:02 -08:00
Michael Shamoon
355efadf87 Inherited permissions 2022-11-15 20:54:57 -08:00
Michael Shamoon
927a9781ad implement superuser select-permissions disable 2022-11-15 01:06:12 -08:00
Michael Shamoon
70eb22df42 Add Django model permissions to API endpoints 2022-11-15 00:44:32 -08:00
Michael Shamoon
f461485aa0 frontend permissions dialogs 2022-11-15 00:44:32 -08:00
Michael Shamoon
b6f1ced455 retain user / group permissions the UI doesnt use 2022-11-15 00:44:32 -08:00
Michael Shamoon
10f36870e6 Merge frontend user model 2022-11-13 21:31:46 -08:00
Michael Shamoon
fdaf9e9b46 Revert "fix: update user permissions and groups, update group permissions"
This reverts commit 57b709824f.
2022-11-13 14:18:44 -08:00
Kaaybi
57b709824f fix: update user permissions and groups, update group permissions 2022-11-13 14:02:54 -08:00
Michael Shamoon
c7b46ac861 skeleton user / group admin dialogs [WIP] 2022-11-13 09:06:56 -08:00
Michael Shamoon
bf28a512c6 dynamic loading of settings tab contents 2022-11-12 14:46:57 -08:00
Kaaybi
4333bd58cf feat: add users and groups API routes 2022-11-12 13:46:50 -08:00
Michael Shamoon
96a29883cd Refactor permissions to use enums, permissions service 2022-11-12 04:31:42 -08:00
Michael Shamoon
59e359ff98 Refactor permissions check code
Directly check permissions and no subscription (uisettings is always initialized on frontend startup)
update permission directive to accept single string
add explicit management permission name
2022-11-11 15:45:37 -08:00
Kaaybi
4603813896 feat: reflect django permissions on UI 2022-11-11 18:33:04 +00:00
393 changed files with 63607 additions and 45153 deletions

View File

@@ -1,6 +1,6 @@
{
"qpdf": {
"version": "11.2.0"
"version": "11.3.0"
},
"jbig2enc": {
"version": "0.29",

19
.codecov.yml Normal file
View File

@@ -0,0 +1,19 @@
# https://docs.codecov.com/docs/pull-request-comments
# codecov will only comment if coverage changes
comment:
require_changes: true
coverage:
status:
project:
default:
# https://docs.codecov.com/docs/commit-status#threshold
threshold: 1%
# https://docs.codecov.com/docs/commit-status#only_pulls
only_pulls: true
patch:
default:
# For the changed lines only, target 75% covered, but
# allow as low as 50%
target: 75%
threshold: 25%
only_pulls: true

View File

@@ -40,7 +40,7 @@ categories:
labels:
- 'frontend'
- 'backend'
collapse-after: 0
collapse-after: 1
include-labels:
- 'enhancement'
- 'bug'
@@ -54,6 +54,8 @@ include-labels:
- 'ci-cd'
- 'breaking-change'
- 'notable'
exclude-labels:
- 'skip-changelog'
category-template: '### $TITLE'
change-template: '- $TITLE @$AUTHOR ([#$NUMBER]($URL))'
change-title-escapes: '\<*_&#@'

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env python3
import json
import logging
import os
@@ -7,6 +6,7 @@ import subprocess
from argparse import ArgumentParser
from typing import Dict
from typing import Final
from typing import Iterator
from typing import List
from typing import Optional
@@ -18,11 +18,14 @@ from github import GithubContainerRegistryApi
logger = logging.getLogger("cleanup-tags")
class DockerManifest2:
class ImageProperties:
"""
Data class wrapping the Docker Image Manifest Version 2.
Data class wrapping the properties of an entry in the image index
manifests list. It is NOT an actual image with layers, etc
See https://docs.docker.com/registry/spec/manifest-v2-2/
https://docs.docker.com/registry/spec/manifest-v2-2/
https://github.com/opencontainers/image-spec/blob/main/manifest.md
https://github.com/opencontainers/image-spec/blob/main/descriptor.md
"""
def __init__(self, data: Dict) -> None:
@@ -39,6 +42,45 @@ class DockerManifest2:
self.platform = f"{platform_data_os}/{platform_arch}{platform_variant}"
class ImageIndex:
"""
Data class wrapping up logic for an OCI Image Index
JSON data. Primary use is to access the manifests listing
See https://github.com/opencontainers/image-spec/blob/main/image-index.md
"""
def __init__(self, package_url: str, tag: str) -> None:
self.qualified_name = f"{package_url}:{tag}"
logger.info(f"Getting image index for {self.qualified_name}")
try:
proc = subprocess.run(
[
shutil.which("docker"),
"buildx",
"imagetools",
"inspect",
"--raw",
self.qualified_name,
],
capture_output=True,
check=True,
)
self._data = json.loads(proc.stdout)
except subprocess.CalledProcessError as e:
logger.error(
f"Failed to get image index for {self.qualified_name}: {e.stderr}",
)
raise e
@property
def image_pointers(self) -> Iterator[ImageProperties]:
for manifest_data in self._data["manifests"]:
yield ImageProperties(manifest_data)
class RegistryTagsCleaner:
"""
This is the base class for the image registry cleaning. Given a package
@@ -85,7 +127,10 @@ class RegistryTagsCleaner:
def clean(self):
"""
This method will delete image versions, based on the selected tags to delete
This method will delete image versions, based on the selected tags to delete.
It behaves more like an unlinking than actual deletion. Removing the tag
simply removes a pointer to an image, but the actual image data remains accessible
if one has the sha256 digest of it.
"""
for tag_to_delete in self.tags_to_delete:
package_version_info = self.all_pkgs_tags_to_version[tag_to_delete]
@@ -149,27 +194,17 @@ class RegistryTagsCleaner:
# Parse manifests to locate digests pointed to
for tag in sorted(self.tags_to_keep):
full_name = f"ghcr.io/{self.repo_owner}/{self.package_name}:{tag}"
logger.info(f"Checking manifest for {full_name}")
try:
proc = subprocess.run(
[
shutil.which("docker"),
"manifest",
"inspect",
full_name,
],
capture_output=True,
image_index = ImageIndex(
f"ghcr.io/{self.repo_owner}/{self.package_name}",
tag,
)
manifest_list = json.loads(proc.stdout)
for manifest_data in manifest_list["manifests"]:
manifest = DockerManifest2(manifest_data)
for manifest in image_index.image_pointers:
if manifest.digest in untagged_versions:
logger.info(
f"Skipping deletion of {manifest.digest},"
f" referred to by {full_name}"
f" referred to by {image_index.qualified_name}"
f" for {manifest.platform}",
)
del untagged_versions[manifest.digest]
@@ -241,6 +276,55 @@ class RegistryTagsCleaner:
# By default, keep anything which is tagged
self.tags_to_keep = list(set(self.all_pkgs_tags_to_version.keys()))
def check_remaining_tags_valid(self):
"""
Checks the non-deleted tags are still valid. The assumption is if the
manifest is can be inspected and each image manifest if points to can be
inspected, the image will still pull.
https://github.com/opencontainers/image-spec/blob/main/image-index.md
"""
logger.info("Beginning confirmation step")
a_tag_failed = False
for tag in sorted(self.tags_to_keep):
try:
image_index = ImageIndex(
f"ghcr.io/{self.repo_owner}/{self.package_name}",
tag,
)
for manifest in image_index.image_pointers:
logger.info(f"Checking {manifest.digest} for {manifest.platform}")
# This follows the pointer from the index to an actual image, layers and all
# Note the format is @
digest_name = f"ghcr.io/{self.repo_owner}/{self.package_name}@{manifest.digest}"
try:
subprocess.run(
[
shutil.which("docker"),
"buildx",
"imagetools",
"inspect",
"--raw",
digest_name,
],
capture_output=True,
check=True,
)
except subprocess.CalledProcessError as e:
logger.error(f"Failed to inspect digest: {e.stderr}")
a_tag_failed = True
except subprocess.CalledProcessError as e:
a_tag_failed = True
logger.error(f"Failed to inspect: {e.stderr}")
continue
if a_tag_failed:
raise Exception("At least one image tag failed to inspect")
class MainImageTagsCleaner(RegistryTagsCleaner):
def decide_what_tags_to_keep(self):
@@ -301,12 +385,10 @@ class MainImageTagsCleaner(RegistryTagsCleaner):
class LibraryTagsCleaner(RegistryTagsCleaner):
"""
Exists for the off change that someday, the installer library images
Exists for the off chance that someday, the installer library images
will need their own logic
"""
pass
def _main():
parser = ArgumentParser(
@@ -397,6 +479,10 @@ def _main():
# Clean images which are untagged
cleaner.clean_untagged(args.is_manifest)
# Verify remaining tags still pull
if args.is_manifest:
cleaner.check_remaining_tags_valid()
if __name__ == "__main__":
_main()

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env python3
import logging

1
.github/scripts/get-build-json.py vendored Executable file → Normal file
View File

@@ -1,4 +1,3 @@
#!/usr/bin/env python3
"""
This is a helper script for the mutli-stage Docker image builder.
It provides a single point of configuration for package version control.

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env python3
"""
This module contains some useful classes for interacting with the Github API.
The full documentation for the API can be found here: https://docs.github.com/en/rest
@@ -162,10 +161,7 @@ class ContainerPackage(_EndpointResponse):
Returns True if the image has at least one tag which matches the given regex,
False otherwise
"""
for tag in self.tags:
if re.match(pattern, tag) is not None:
return True
return False
return any(re.match(pattern, tag) is not None for tag in self.tags)
def __repr__(self):
return f"Package {self.name}"

View File

@@ -16,7 +16,7 @@ on:
env:
# This is the version of pipenv all the steps will use
# If changing this, change Dockerfile
DEFAULT_PIP_ENV_VERSION: "2022.11.30"
DEFAULT_PIP_ENV_VERSION: "2023.3.20"
# This is the default version of Python to use in most steps
# If changing this, change Dockerfile
DEFAULT_PYTHON_VERSION: "3.9"
@@ -113,16 +113,12 @@ jobs:
PAPERLESS_MAIL_TEST_HOST: ${{ secrets.TEST_MAIL_HOST }}
PAPERLESS_MAIL_TEST_USER: ${{ secrets.TEST_MAIL_USER }}
PAPERLESS_MAIL_TEST_PASSWD: ${{ secrets.TEST_MAIL_PASSWD }}
# Skip Tests which require convert
PAPERLESS_TEST_SKIP_CONVERT: 1
# Enable Gotenberg end to end testing
GOTENBERG_LIVE: 1
steps:
-
name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
-
name: Start containers
run: |
@@ -145,6 +141,10 @@ jobs:
run: |
sudo apt-get update -qq
sudo apt-get install -qq --no-install-recommends unpaper tesseract-ocr imagemagick ghostscript libzbar0 poppler-utils
-
name: Configure ImageMagick
run: |
sudo cp docker/imagemagick-policy.xml /etc/ImageMagick-6/policy.xml
-
name: Install Python dependencies
run: |
@@ -160,27 +160,14 @@ jobs:
cd src/
pipenv --python ${{ steps.setup-python.outputs.python-version }} run pytest -ra
-
name: Get changed files
id: changed-files-specific
uses: tj-actions/changed-files@v35
name: Upload coverage to Codecov
if: ${{ matrix.python-version == env.DEFAULT_PYTHON_VERSION }}
uses: codecov/codecov-action@v3
with:
files: |
src/**
-
name: List all changed files
run: |
for file in ${{ steps.changed-files-specific.outputs.all_changed_files }}; do
echo "${file} was changed"
done
-
name: Publish coverage results
if: matrix.python-version == ${{ env.DEFAULT_PYTHON_VERSION }} && steps.changed-files-specific.outputs.any_changed == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# https://github.com/coveralls-clients/coveralls-python/issues/251
run: |
cd src/
pipenv --python ${{ steps.setup-python.outputs.python-version }} run coveralls --service=github
# not required for public repos, but intermittently fails otherwise
token: ${{ secrets.CODECOV_TOKEN }}
# future expansion
flags: backend
-
name: Stop containers
if: always()
@@ -203,6 +190,8 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: 'src-ui/package-lock.json'
- run: cd src-ui && npm ci
- run: cd src-ui && npm run lint
- run: cd src-ui && npm run test
@@ -212,12 +201,6 @@ jobs:
name: Prepare Docker Pipeline Data
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/heads/feature-') || github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/beta' || contains(github.ref, 'beta.rc') || startsWith(github.ref, 'refs/tags/v'))
runs-on: ubuntu-22.04
# If the push triggered the installer library workflow, wait for it to
# complete here. This ensures the required versions for the final
# image have been built, while not waiting at all if the versions haven't changed
concurrency:
group: build-installer-library
cancel-in-progress: false
needs:
- documentation
- tests-backend
@@ -320,6 +303,7 @@ jobs:
images: |
ghcr.io/${{ needs.prepare-docker-build.outputs.ghcr-repository }}
name=paperlessngx/paperless-ngx,enable=${{ steps.docker-hub.outputs.enable }}
name=quay.io/paperlessngx/paperless-ngx,enable=${{ steps.docker-hub.outputs.enable }}
tags: |
# Tag branches with branch name
type=ref,event=branch
@@ -351,9 +335,18 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to Quay.io
uses: docker/login-action@v2
# Don't attempt to login is not pushing to Docker Hub
if: steps.docker-hub.outputs.enable == 'true'
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_ROBOT_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
@@ -448,21 +441,48 @@ jobs:
-
name: Move files
run: |
mkdir dist
mkdir dist/paperless-ngx
mkdir dist/paperless-ngx/scripts
cp .dockerignore .env Dockerfile Pipfile Pipfile.lock requirements.txt LICENSE README.md dist/paperless-ngx/
cp paperless.conf.example dist/paperless-ngx/paperless.conf
cp gunicorn.conf.py dist/paperless-ngx/gunicorn.conf.py
cp -r docker/ dist/paperless-ngx/docker
cp scripts/*.service scripts/*.sh scripts/*.socket dist/paperless-ngx/scripts/
cp -r src/ dist/paperless-ngx/src
cp -r docs/_build/html/ dist/paperless-ngx/docs
mv static dist/paperless-ngx
echo "Making dist folders"
for directory in dist \
dist/paperless-ngx \
dist/paperless-ngx/scripts;
do
mkdir --verbose --parents ${directory}
done
echo "Copying basic files"
for file_name in .dockerignore \
.env \
Dockerfile \
Pipfile \
Pipfile.lock \
requirements.txt \
LICENSE \
README.md \
paperless.conf.example \
gunicorn.conf.py
do
cp --verbose ${file_name} dist/paperless-ngx/
done
mv --verbose dist/paperless-ngx/paperless.conf.example dist/paperless-ngx/paperless.conf
echo "Copying Docker related files"
cp --recursive docker/ dist/paperless-ngx/docker
echo "Copying startup scripts"
cp --verbose scripts/*.service scripts/*.sh scripts/*.socket dist/paperless-ngx/scripts/
echo "Copying source files"
cp --recursive src/ dist/paperless-ngx/src
echo "Copying documentation"
cp --recursive docs/_build/html/ dist/paperless-ngx/docs
mv --verbose static dist/paperless-ngx
-
name: Make release package
run: |
echo "Creating release archive"
cd dist
sudo chown -R 1000:1000 paperless-ngx/
tar -cJf paperless-ngx.tar.xz paperless-ngx/
-
name: Upload release artifact
@@ -578,5 +598,5 @@ jobs:
owner,
repo,
issue_number: result.data.number,
labels: ['documentation']
labels: ['documentation', 'skip-changelog']
});

View File

@@ -62,9 +62,9 @@ jobs:
with:
python-version: "3.10"
-
name: Install httpx
name: Install Python libraries
run: |
python -m pip install httpx
python -m pip install httpx docker
#
# Clean up primary package
#
@@ -81,13 +81,3 @@ jobs:
if: "${{ env.TOKEN != '' }}"
run: |
python ${GITHUB_WORKSPACE}/.github/scripts/cleanup-tags.py --untagged --delete "${{ matrix.cache-name }}"
#
# Verify tags which are left still pull
#
-
name: Check all tags still pull
run: |
ghcr_name=$(echo "ghcr.io/${GITHUB_REPOSITORY_OWNER}/${{ matrix.primary-name }}" | awk '{ print tolower($0) }')
echo "Pulling all tags of ${ghcr_name}"
docker pull --quiet --all-tags ${ghcr_name}
docker image list

View File

@@ -169,3 +169,142 @@ jobs:
PIKEPDF_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.pikepdf-json).version }}
PILLOW_VERSION=${{ needs.prepare-docker-build.outputs.pillow-version }}
LXML_VERSION=${{ needs.prepare-docker-build.outputs.lxml-version }}
commit-binary-files:
name: Store installers
needs:
- prepare-docker-build
- build-qpdf-debs
- build-jbig2enc
- build-psycopg2-wheel
- build-pikepdf-wheel
runs-on: ubuntu-22.04
steps:
-
name: Checkout
uses: actions/checkout@v3
with:
ref: binary-library
-
name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.9"
-
name: Install system dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -qq --no-install-recommends tree
-
name: Extract qpdf files
run: |
version=${{ fromJSON(needs.prepare-docker-build.outputs.qpdf-json).version }}
tag=${{ fromJSON(needs.prepare-docker-build.outputs.qpdf-json).image_tag }}
docker pull --quiet ${tag}
docker create --name qpdf-extract ${tag}
mkdir --parents qpdf/${version}/amd64
docker cp qpdf-extract:/usr/src/qpdf/${version}/amd64 qpdf/${version}
mkdir --parents qpdf/${version}/arm64
docker cp qpdf-extract:/usr/src/qpdf/${version}/arm64 qpdf/${version}
mkdir --parents qpdf/${version}/armv7
docker cp qpdf-extract:/usr/src/qpdf/${version}/armv7 qpdf/${version}
-
name: Extract psycopg2 files
run: |
version=${{ fromJSON(needs.prepare-docker-build.outputs.psycopg2-json).version }}
tag=${{ fromJSON(needs.prepare-docker-build.outputs.psycopg2-json).image_tag }}
docker pull --quiet --platform linux/amd64 ${tag}
docker create --platform linux/amd64 --name psycopg2-extract ${tag}
mkdir --parents psycopg2/${version}/amd64
docker cp psycopg2-extract:/usr/src/wheels/ psycopg2/${version}/amd64
mv psycopg2/${version}/amd64/wheels/* psycopg2/${version}/amd64
rm -r psycopg2/${version}/amd64/wheels/
docker rm psycopg2-extract
docker pull --quiet --platform linux/arm64 ${tag}
docker create --platform linux/arm64 --name psycopg2-extract ${tag}
mkdir --parents psycopg2/${version}/arm64
docker cp psycopg2-extract:/usr/src/wheels/ psycopg2/${version}/arm64
mv psycopg2/${version}/arm64/wheels/* psycopg2/${version}/arm64
rm -r psycopg2/${version}/arm64/wheels/
docker rm psycopg2-extract
docker pull --quiet --platform linux/arm/v7 ${tag}
docker create --platform linux/arm/v7 --name psycopg2-extract ${tag}
mkdir --parents psycopg2/${version}/armv7
docker cp psycopg2-extract:/usr/src/wheels/ psycopg2/${version}/armv7
mv psycopg2/${version}/armv7/wheels/* psycopg2/${version}/armv7
rm -r psycopg2/${version}/armv7/wheels/
docker rm psycopg2-extract
-
name: Extract pikepdf files
run: |
version=${{ fromJSON(needs.prepare-docker-build.outputs.pikepdf-json).version }}
tag=${{ fromJSON(needs.prepare-docker-build.outputs.pikepdf-json).image_tag }}
docker pull --quiet --platform linux/amd64 ${tag}
docker create --platform linux/amd64 --name pikepdf-extract ${tag}
mkdir --parents pikepdf/${version}/amd64
docker cp pikepdf-extract:/usr/src/wheels/ pikepdf/${version}/amd64
mv pikepdf/${version}/amd64/wheels/* pikepdf/${version}/amd64
rm -r pikepdf/${version}/amd64/wheels/
docker rm pikepdf-extract
docker pull --quiet --platform linux/arm64 ${tag}
docker create --platform linux/arm64 --name pikepdf-extract ${tag}
mkdir --parents pikepdf/${version}/arm64
docker cp pikepdf-extract:/usr/src/wheels/ pikepdf/${version}/arm64
mv pikepdf/${version}/arm64/wheels/* pikepdf/${version}/arm64
rm -r pikepdf/${version}/arm64/wheels/
docker rm pikepdf-extract
docker pull --quiet --platform linux/arm/v7 ${tag}
docker create --platform linux/arm/v7 --name pikepdf-extract ${tag}
mkdir --parents pikepdf/${version}/armv7
docker cp pikepdf-extract:/usr/src/wheels/ pikepdf/${version}/armv7
mv pikepdf/${version}/armv7/wheels/* pikepdf/${version}/armv7
rm -r pikepdf/${version}/armv7/wheels/
docker rm pikepdf-extract
-
name: Extract jbig2enc files
run: |
version=${{ fromJSON(needs.prepare-docker-build.outputs.jbig2enc-json).version }}
tag=${{ fromJSON(needs.prepare-docker-build.outputs.jbig2enc-json).image_tag }}
docker pull --quiet --platform linux/amd64 ${tag}
docker create --platform linux/amd64 --name jbig2enc-extract ${tag}
mkdir --parents jbig2enc/${version}/amd64
docker cp jbig2enc-extract:/usr/src/jbig2enc/build jbig2enc/${version}/amd64/
mv jbig2enc/${version}/amd64/build/* jbig2enc/${version}/amd64/
docker rm jbig2enc-extract
docker pull --quiet --platform linux/arm64 ${tag}
docker create --platform linux/arm64 --name jbig2enc-extract ${tag}
mkdir --parents jbig2enc/${version}/arm64
docker cp jbig2enc-extract:/usr/src/jbig2enc/build jbig2enc/${version}/arm64
mv jbig2enc/${version}/arm64/build/* jbig2enc/${version}/arm64/
docker rm jbig2enc-extract
docker pull --quiet --platform linux/arm/v7 ${tag}
docker create --platform linux/arm/v7 --name jbig2enc-extract ${tag}
mkdir --parents jbig2enc/${version}/armv7
docker cp jbig2enc-extract:/usr/src/jbig2enc/build jbig2enc/${version}/armv7
mv jbig2enc/${version}/armv7/build/* jbig2enc/${version}/armv7/
docker rm jbig2enc-extract
-
name: Show file structure
run: |
tree .
-
name: Commit files
run: |
git config --global user.name "github-actions"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add pikepdf/ qpdf/ psycopg2/ jbig2enc/
git commit -m "Updating installer packages" || true
git push origin || true

View File

@@ -28,7 +28,7 @@ jobs:
if: github.event_name == 'issues' && (github.event.action == 'opened' || github.event.action == 'reopened')
steps:
- name: Add issue to project and set status to ${{ env.todo }}
uses: leonsteinhaeuser/project-beta-automations@v2.0.1
uses: leonsteinhaeuser/project-beta-automations@v2.1.0
with:
gh_token: ${{ secrets.GH_TOKEN }}
organization: paperless-ngx
@@ -44,7 +44,7 @@ jobs:
if: github.event_name == 'pull_request_target' && (github.event.action == 'opened' || github.event.action == 'reopened') && github.event.pull_request.user.login != 'dependabot'
steps:
- name: Add PR to project and set status to "Needs Review"
uses: leonsteinhaeuser/project-beta-automations@v2.0.1
uses: leonsteinhaeuser/project-beta-automations@v2.1.0
with:
gh_token: ${{ secrets.GH_TOKEN }}
organization: paperless-ngx

View File

@@ -45,7 +45,7 @@ jobs:
uses: docker/setup-qemu-action@v2
-
name: Build ${{ fromJSON(inputs.build-json).name }}
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: .
file: ${{ inputs.dockerfile }}

1
.gitignore vendored
View File

@@ -73,6 +73,7 @@ virtualenv
.venv/
/docker-compose.env
/docker-compose.yml
.ruff_cache/
# Used for development
scripts/import-for-development

View File

@@ -36,39 +36,14 @@ repos:
- markdown
exclude: "(^Pipfile\\.lock$)"
# Python hooks
- repo: https://github.com/asottile/reorder_python_imports
rev: v3.9.0
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.0.259'
hooks:
- id: reorder-python-imports
exclude: "(migrations)"
- repo: https://github.com/asottile/yesqa
rev: "v1.4.0"
hooks:
- id: yesqa
exclude: "(migrations)"
- repo: https://github.com/asottile/add-trailing-comma
rev: "v2.4.0"
hooks:
- id: add-trailing-comma
exclude: "(migrations)"
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
files: ^src/
args:
- "--config=./src/setup.cfg"
- id: ruff
- repo: https://github.com/psf/black
rev: 22.12.0
hooks:
- id: black
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
hooks:
- id: pyupgrade
exclude: "(migrations)"
args:
- "--py38-plus"
# Dockerfile hooks
- repo: https://github.com/AleksaC/hadolint-py
rev: v2.10.0

View File

@@ -1 +1 @@
3.8.15
3.8.16

23
.ruff.toml Normal file
View File

@@ -0,0 +1,23 @@
# https://beta.ruff.rs/docs/settings/
# https://beta.ruff.rs/docs/rules/
select = ["F", "E", "W", "UP", "COM", "DJ", "EXE", "ISC", "ICN", "G201", "INP", "PIE", "RSE", "SIM", "TID", "PLC", "PLE", "RUF"]
# TODO PTH
ignore = ["DJ001", "SIM105"]
fix = true
line-length = 88
respect-gitignore = true
src = ["src"]
target-version = "py38"
format = "grouped"
show-fixes = true
[per-file-ignores]
".github/scripts/*.py" = ["E501", "INP001", "SIM117"]
"docker/wait-for-redis.py" = ["INP001"]
"*/tests/*.py" = ["E501", "SIM117"]
"*/migrations/*.py" = ["E501", "SIM"]
"src/paperless_tesseract/tests/test_parser.py" = ["RUF001"]
"src/documents/models.py" = ["SIM115"]
[isort]
force-single-line = true

View File

@@ -1,26 +1,12 @@
# syntax=docker/dockerfile:1.4
# https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/reference.md
# Pull the installer images from the library
# These are all built previously
# They provide either a .deb or .whl
ARG JBIG2ENC_VERSION
ARG QPDF_VERSION
ARG PIKEPDF_VERSION
ARG PSYCOPG2_VERSION
FROM ghcr.io/paperless-ngx/paperless-ngx/builder/jbig2enc:${JBIG2ENC_VERSION} as jbig2enc-builder
FROM --platform=$BUILDPLATFORM ghcr.io/paperless-ngx/paperless-ngx/builder/qpdf:${QPDF_VERSION} as qpdf-builder
FROM ghcr.io/paperless-ngx/paperless-ngx/builder/pikepdf:${PIKEPDF_VERSION} as pikepdf-builder
FROM ghcr.io/paperless-ngx/paperless-ngx/builder/psycopg2:${PSYCOPG2_VERSION} as psycopg2-builder
# Stage: compile-frontend
# Purpose: Compiles the frontend
# Notes:
# - Does NPM stuff with Typescript and such
FROM --platform=$BUILDPLATFORM node:16-bullseye-slim AS compile-frontend
# This stage compiles the frontend
# This stage runs once for the native platform, as the outputs are not
# dependent on target arch
# Inputs: None
COPY ./src-ui /src/src-ui
WORKDIR /src/src-ui
@@ -30,25 +16,27 @@ RUN set -eux \
RUN set -eux \
&& ./node_modules/.bin/ng build --configuration production
# Stage: pipenv-base
# Purpose: Generates a requirements.txt file for building
# Comments:
# - pipenv dependencies are not left in the final image
# - pipenv can't touch the final image somehow
FROM --platform=$BUILDPLATFORM python:3.9-slim-bullseye as pipenv-base
# This stage generates the requirements.txt file using pipenv
# This stage runs once for the native platform, as the outputs are not
# dependent on target arch
# This way, pipenv dependencies are not left in the final image
# nor can pipenv mess up the final image somehow
# Inputs: None
WORKDIR /usr/src/pipenv
COPY Pipfile* ./
RUN set -eux \
&& echo "Installing pipenv" \
&& python3 -m pip install --no-cache-dir --upgrade pipenv==2022.11.30 \
&& python3 -m pip install --no-cache-dir --upgrade pipenv==2023.3.20 \
&& echo "Generating requirement.txt" \
&& pipenv requirements > requirements.txt
# Stage: main-app
# Purpose: The final image
# Comments:
# - Don't leave anything extra in here
FROM python:3.9-slim-bullseye as main-app
LABEL org.opencontainers.image.authors="paperless-ngx team <hello@paperless-ngx.com>"
@@ -58,30 +46,14 @@ LABEL org.opencontainers.image.url="https://github.com/paperless-ngx/paperless-n
LABEL org.opencontainers.image.licenses="GPL-3.0-only"
ARG DEBIAN_FRONTEND=noninteractive
# Buildx provided
ARG TARGETARCH
ARG TARGETVARIANT
# Workflow provided
ARG QPDF_VERSION
#
# Begin installation and configuration
# Order the steps below from least often changed to most
#
# copy jbig2enc
# Basically will never change again
COPY --from=jbig2enc-builder /usr/src/jbig2enc/src/.libs/libjbig2enc* /usr/local/lib/
COPY --from=jbig2enc-builder /usr/src/jbig2enc/src/jbig2 /usr/local/bin/
COPY --from=jbig2enc-builder /usr/src/jbig2enc/src/*.h /usr/local/include/
# Packages need for running
ARG RUNTIME_PACKAGES="\
# Python
python3 \
python3-pip \
python3-setuptools \
# General utils
curl \
# Docker specific
@@ -145,7 +117,7 @@ RUN set -eux \
&& apt-get install --yes --quiet --no-install-recommends ${RUNTIME_PACKAGES} \
&& rm -rf /var/lib/apt/lists/* \
&& echo "Installing supervisor" \
&& python3 -m pip install --default-timeout=1000 --upgrade --no-cache-dir supervisor==4.2.4
&& python3 -m pip install --default-timeout=1000 --upgrade --no-cache-dir supervisor==4.2.5
# Copy gunicorn config
# Changes very infrequently
@@ -154,7 +126,6 @@ WORKDIR /usr/src/paperless/
COPY gunicorn.conf.py .
# setup docker-specific things
# Use mounts to avoid copying installer files into the image
# These change sometimes, but rarely
WORKDIR /usr/src/paperless/src/docker/
@@ -195,22 +166,42 @@ RUN set -eux \
&& chmod +x install_management_commands.sh \
&& ./install_management_commands.sh
# Buildx provided, must be defined to use though
ARG TARGETARCH
ARG TARGETVARIANT
# Workflow provided, defaults set for manual building
ARG JBIG2ENC_VERSION=0.29
ARG QPDF_VERSION=11.3.0
ARG PIKEPDF_VERSION=7.1.1
ARG PSYCOPG2_VERSION=2.9.5
# Install the built packages from the installer library images
# Use mounts to avoid copying installer files into the image
# These change sometimes
RUN --mount=type=bind,from=qpdf-builder,target=/qpdf \
--mount=type=bind,from=psycopg2-builder,target=/psycopg2 \
--mount=type=bind,from=pikepdf-builder,target=/pikepdf \
set -eux \
RUN set -eux \
&& echo "Getting binaries" \
&& mkdir paperless-ngx \
&& curl --fail --silent --show-error --output paperless-ngx.tar.gz --location https://github.com/paperless-ngx/paperless-ngx/archive/ba28a1e16c27d121b644b4f6bdb78855a2850561.tar.gz \
&& tar -xf paperless-ngx.tar.gz --directory paperless-ngx --strip-components=1 \
&& cd paperless-ngx \
# Setting a specific revision ensures we know what this installed
# and ensures cache breaking on changes
&& echo "Installing jbig2enc" \
&& cp ./jbig2enc/${JBIG2ENC_VERSION}/${TARGETARCH}${TARGETVARIANT}/jbig2 /usr/local/bin/ \
&& cp ./jbig2enc/${JBIG2ENC_VERSION}/${TARGETARCH}${TARGETVARIANT}/libjbig2enc* /usr/local/lib/ \
&& echo "Installing qpdf" \
&& apt-get install --yes --no-install-recommends /qpdf/usr/src/qpdf/${QPDF_VERSION}/${TARGETARCH}${TARGETVARIANT}/libqpdf29_*.deb \
&& apt-get install --yes --no-install-recommends /qpdf/usr/src/qpdf/${QPDF_VERSION}/${TARGETARCH}${TARGETVARIANT}/qpdf_*.deb \
&& apt-get install --yes --no-install-recommends ./qpdf/${QPDF_VERSION}/${TARGETARCH}${TARGETVARIANT}/libqpdf29_*.deb \
&& apt-get install --yes --no-install-recommends ./qpdf/${QPDF_VERSION}/${TARGETARCH}${TARGETVARIANT}/qpdf_*.deb \
&& echo "Installing pikepdf and dependencies" \
&& python3 -m pip install --no-cache-dir /pikepdf/usr/src/wheels/*.whl \
&& python3 -m pip install --no-cache-dir ./pikepdf/${PIKEPDF_VERSION}/${TARGETARCH}${TARGETVARIANT}/*.whl \
&& python3 -m pip list \
&& echo "Installing psycopg2" \
&& python3 -m pip install --no-cache-dir /psycopg2/usr/src/wheels/psycopg2*.whl \
&& python3 -m pip list
&& python3 -m pip install --no-cache-dir ./psycopg2/${PSYCOPG2_VERSION}/${TARGETARCH}${TARGETVARIANT}/psycopg2*.whl \
&& python3 -m pip list \
&& echo "Cleaning up image layer" \
&& cd ../ \
&& rm -rf paperless-ngx \
&& rm paperless-ngx.tar.gz
WORKDIR /usr/src/paperless/src/
@@ -254,11 +245,12 @@ COPY ./src ./
COPY --from=compile-frontend /src/src/documents/static/frontend/ ./documents/static/frontend/
# add users, setup scripts
# Mount the compiled frontend to expected location
RUN set -eux \
&& addgroup --gid 1000 paperless \
&& useradd --uid 1000 --gid paperless --home-dir /usr/src/paperless paperless \
&& chown -R paperless:paperless ../ \
&& gosu paperless python3 manage.py collectstatic --clear --no-input \
&& chown -R paperless:paperless /usr/src/paperless \
&& gosu paperless python3 manage.py collectstatic --clear --no-input --link \
&& gosu paperless python3 manage.py compilemessages
VOLUME ["/usr/src/paperless/data", \

46
Pipfile
View File

@@ -12,15 +12,20 @@ name = "piwheels"
dateparser = "~=1.1"
django = "~=4.1"
django-cors-headers = "*"
django-celery-results = "*"
django-compression-middleware = "*"
django-guardian = "*"
django-extensions = "*"
django-filter = "~=22.1"
djangorestframework = "~=3.14"
djangorestframework-guardian = "*"
django-ipware = "*"
filelock = "*"
gunicorn = "*"
imap-tools = "*"
langdetect = "*"
pathvalidate = "*"
pillow = "~=9.3"
pillow = "~=9.4"
pikepdf = "*"
python-gnupg = "*"
python-dotenv = "*"
@@ -29,10 +34,10 @@ python-magic = "*"
psycopg2 = "*"
rapidfuzz = "*"
redis = {extras = ["hiredis"], version = "*"}
scikit-learn = "~=1.1"
scikit-learn = "~=1.2"
numpy = "*"
whitenoise = "~=6.2"
watchdog = "~=2.1"
whitenoise = "~=6.3"
watchdog = "~=2.2"
whoosh="~=2.7"
inotifyrecursive = "~=0.3"
ocrmypdf = "~=14.0"
@@ -41,33 +46,25 @@ tika = "*"
# TODO: This will sadly also install daphne+dependencies,
# which an ASGI server we don't need. Adds about 15MB image size.
channels = "~=3.0"
channels-redis = "*"
uvicorn = {extras = ["standard"], version = "*"}
concurrent-log-handler = "*"
"pdfminer.six" = "*"
pyzbar = "*"
mysqlclient = "*"
celery = {extras = ["redis"], version = "*"}
django-celery-results = "*"
setproctitle = "*"
nltk = "*"
pdf2image = "*"
flower = "*"
bleach = "*"
zxing-cpp = {version = "*", platform_machine = "== 'x86_64'"}
#
# Packages locked due to issues (try to check if these are fixed in a release every so often)
#
# Pin this until piwheels is building 1.9 (see https://www.piwheels.org/project/scipy/)
scipy = "==1.8.1"
# Newer versions aren't builting yet (see https://www.piwheels.org/project/cryptography/)
cryptography = "==38.0.1"
# Locked version until https://github.com/django/channels_redis/issues/332
# is resolved
channels-redis = "==3.4.1"
[dev-packages]
coveralls = "*"
factory-boy = "*"
@@ -81,3 +78,24 @@ black = "*"
pre-commit = "*"
imagehash = "*"
mkdocs-material = "*"
ruff = "*"
[typing-dev]
mypy = "*"
types-Pillow = "*"
django-filter-stubs = "*"
types-python-dateutil = "*"
djangorestframework-stubs = {extras= ["compatible-mypy"], version="*"}
celery-types = "*"
django-stubs = {extras= ["compatible-mypy"], version="*"}
types-dateparser = "*"
types-bleach = "*"
types-humanfriendly = "*"
types-redis = "*"
types-tqdm = "*"
types-Markdown = "*"
types-Pygments = "*"
types-backports = "*"
types-colorama = "*"
types-psycopg2 = "*"
types-setuptools = "*"

2431
Pipfile.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
[![ci](https://github.com/paperless-ngx/paperless-ngx/workflows/ci/badge.svg)](https://github.com/paperless-ngx/paperless-ngx/actions)
[![Crowdin](https://badges.crowdin.net/paperless-ngx/localized.svg)](https://crowdin.com/project/paperless-ngx)
[![Documentation Status](https://img.shields.io/github/deployments/paperless-ngx/paperless-ngx/github-pages?label=docs)](https://docs.paperless-ngx.com)
[![Coverage Status](https://coveralls.io/repos/github/paperless-ngx/paperless-ngx/badge.svg?branch=master)](https://coveralls.io/github/paperless-ngx/paperless-ngx?branch=master)
[![codecov](https://codecov.io/gh/paperless-ngx/paperless-ngx/branch/main/graph/badge.svg?token=VK6OUPJ3TY)](https://codecov.io/gh/paperless-ngx/paperless-ngx)
[![Chat on Matrix](https://matrix.to/img/matrix-badge.svg)](https://matrix.to/#/%23paperlessngx%3Amatrix.org)
[![demo](https://cronitor.io/badges/ve7ItY/production/W5E_B9jkelG9ZbDiNHUPQEVH3MY.svg)](https://demo.paperless-ngx.com)
@@ -101,13 +101,16 @@ For bugs please [open an issue](https://github.com/paperless-ngx/paperless-ngx/i
# Affiliated Projects
Paperless has been around a while now, and people are starting to build stuff on top of it. If you're one of those people, we can add your project to this list:
Paperless has been around for a while now, and people have built tools that interact with it. If you're one of them, please reach out and we can add your project to the list. Current projects include:
- [Paperless App](https://github.com/bauerj/paperless_app): An Android/iOS app for Paperless-ngx. Also works with the original Paperless and 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.
- [Paperless Mobile](https://github.com/astubenbord/paperless-mobile): A modern, feature rich mobile application for Paperless.
- **Mobile**
- [Paperless App](https://github.com/bauerj/paperless_app): An Android/iOS application for Paperless-ngx.
- [Paperless Mobile](https://github.com/astubenbord/paperless-mobile): A modern, feature rich Android app for Paperless-ngx.
- [Paperless Share](https://github.com/qcasey/paperless_share): Share any files from your Android application with Paperless-ngx. Very simple, but works with all mobile scanning apps that allow you to share scanned documents.
- **Desktop**
- [Scan to Paperless](https://github.com/sbrunner/scan-to-paperless): Scan and prepare (crop, deskew, OCR, ...) your documents for use in Paperless-ngx.
# Important Note
Document scanners are typically used to scan sensitive documents. Things like your social insurance number, tax records, invoices, etc. Everything is stored in the clear without encryption. This means that Paperless should never be run on an untrusted host. Instead, I recommend that if you do want to use it, run it locally on a server in your own home.
> Document scanners are typically used to scan sensitive documents like your social insurance number, tax records, invoices, etc. **Paperless-ngx should never be run on an untrusted host** because information is stored in clear text without encryption. No guarantees are made regarding security (but we do try!) and you use the app at your own risk.
> **The safest way to run Paperless-ngx is on a local server in your own home with backups in place**.

View File

@@ -29,7 +29,20 @@ RUN set -eux \
&& ./autogen.sh \
&& ./configure \
&& make \
&& echo "Gathering package data" \
&& dpkg-query -f '${Package;-40}${Version}\n' -W > ./pkg-list.txt \
&& echo "Cleaning up image" \
&& apt-get -y purge ${BUILD_PACKAGES} \
&& apt-get -y autoremove --purge \
&& rm -rf /var/lib/apt/lists/*
&& rm -rf /var/lib/apt/lists/* \
&& echo "Moving files around" \
&& mkdir build \
# Unlink a symlink that causes problems
&& unlink ./src/.libs/libjbig2enc.la \
# Move what the link pointed to
&& mv ./src/libjbig2enc.la ./build/ \
# Move the shared library .so files
&& mv ./src/.libs/libjbig2enc* ./build/ \
# And move the cli binary
&& mv ./src/jbig2 ./build/ \
&& mv ./pkg-list.txt ./build/

View File

@@ -7,12 +7,17 @@
# Default to pulling from the main repo registry when manually building
ARG REPO="paperless-ngx/paperless-ngx"
# This does nothing, except provide a name for a copy below
ARG QPDF_VERSION
FROM --platform=$BUILDPLATFORM ghcr.io/${REPO}/builder/qpdf:${QPDF_VERSION} as qpdf-builder
# This does nothing, except provide a name for a copy below
FROM python:3.9-slim-bullseye as main
#
# Stage: builder
# Purpose:
# - Build the pikepdf wheel
# - Build any dependent wheels which can't be found
#
FROM python:3.9-slim-bullseye as builder
LABEL org.opencontainers.image.description="A intermediate image with pikepdf wheel built"
@@ -100,3 +105,14 @@ RUN set -eux \
&& apt-get -y purge ${BUILD_PACKAGES} \
&& apt-get -y autoremove --purge \
&& rm -rf /var/lib/apt/lists/*
#
# Stage: package
# Purpose: Holds the compiled .whl files in a tiny image to pull
#
FROM alpine:3.17 as package
WORKDIR /usr/src/wheels/
COPY --from=builder /usr/src/wheels/*.whl ./
COPY --from=builder /usr/src/wheels/pkg-list.txt ./

View File

@@ -2,7 +2,12 @@
# Inputs:
# - PSYCOPG2_VERSION - Version to build
FROM python:3.9-slim-bullseye as main
#
# Stage: builder
# Purpose:
# - Build the psycopg2 wheel
#
FROM python:3.9-slim-bullseye as builder
LABEL org.opencontainers.image.description="A intermediate image with psycopg2 wheel built"
@@ -48,3 +53,14 @@ RUN set -eux \
&& apt-get -y purge ${BUILD_PACKAGES} \
&& apt-get -y autoremove --purge \
&& rm -rf /var/lib/apt/lists/*
#
# Stage: package
# Purpose: Holds the compiled .whl files in a tiny image to pull
#
FROM alpine:3.17 as package
WORKDIR /usr/src/wheels/
COPY --from=builder /usr/src/wheels/*.whl ./
COPY --from=builder /usr/src/wheels/pkg-list.txt ./

57
docker-builders/README.md Normal file
View File

@@ -0,0 +1,57 @@
# Installer Library
This folder contains the Dockerfiles for building certain installers or libraries, which are then pulled into the main image.
## [jbig2enc](https://github.com/agl/jbig2enc)
### Why
JBIG is an image coding which can achieve better compression of images for PDFs.
### What
The Docker image builds a shared library file and utility, which is copied into the correct location in the final image.
### Updating
1. Ensure the given qpdf version is present in [Debian bookworm](https://packages.debian.org/bookworm/qpdf)
2. Update `.build-config.json` to the given version
3. If the Debian specific version has incremented, update `Dockerfile.qpdf`
See Also:
- [OCRMyPDF Documentation](https://ocrmypdf.readthedocs.io/en/latest/jbig2.html)
## [psycopg2](https://www.psycopg.org/)
### Why
The pre-built wheels of psycopg2 are built on Debian 9, which provides a quite old version of libpq-dev. This causes issue with authentication methods.
### What
The image builds psycopg2 wheels on Debian 10 and places the produced wheels into `/usr/src/wheels/`.
See Also:
- [Issue 266](https://github.com/paperless-ngx/paperless-ngx/issues/266)
## [qpdf](https://qpdf.readthedocs.io/en/stable/index.html)
### Why
qpdf and it's library provide tools to read, manipulate and fix up PDFs. Version 11 is also required by `pikepdf` 6+ and Debian 9 does not provide above version 10.
### What
The Docker image cross compiles .deb installers for each supported architecture of the main image. The installers are placed in `/usr/src/qpdf/${QPDF_VERSION}/${TARGETARCH}${TARGETVARIANT}/`
## [pikepdf](https://pikepdf.readthedocs.io/en/latest/)
### Why
Required by OCRMyPdf, this is a general purpose library for PDF manipulation in Python via the qpdf libraries.
### What
The built wheels are placed into `/usr/src/wheels/`

View File

@@ -6,7 +6,7 @@
version: "3.7"
services:
gotenberg:
image: docker.io/gotenberg/gotenberg:7.6
image: docker.io/gotenberg/gotenberg:7.8
hostname: gotenberg
container_name: gotenberg
network_mode: host

View File

@@ -59,7 +59,7 @@ services:
- gotenberg
- tika
ports:
- 8000:8000
- "8000:8000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000"]
interval: 30s
@@ -83,7 +83,7 @@ services:
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg:
image: docker.io/gotenberg/gotenberg:7.6
image: docker.io/gotenberg/gotenberg:7.8
restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not
# want to allow external content like tracking pixels or even javascript.

View File

@@ -53,7 +53,7 @@ services:
- db
- broker
ports:
- 8000:8000
- "8000:8000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000"]
interval: 30s

View File

@@ -53,7 +53,7 @@ services:
- db
- broker
ports:
- 8010:8000
- "8010:8000"
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s

View File

@@ -57,7 +57,7 @@ services:
- gotenberg
- tika
ports:
- 8000:8000
- "8000:8000"
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s
@@ -77,7 +77,7 @@ services:
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg:
image: docker.io/gotenberg/gotenberg:7.6
image: docker.io/gotenberg/gotenberg:7.8
restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not

View File

@@ -51,7 +51,7 @@ services:
- db
- broker
ports:
- 8000:8000
- "8000:8000"
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s

View File

@@ -46,7 +46,7 @@ services:
- gotenberg
- tika
ports:
- 8000:8000
- "8000:8000"
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s
@@ -65,7 +65,7 @@ services:
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg:
image: docker.io/gotenberg/gotenberg:7.6
image: docker.io/gotenberg/gotenberg:7.8
restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not

View File

@@ -37,7 +37,7 @@ services:
depends_on:
- broker
ports:
- 8000:8000
- "8000:8000"
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s

View File

@@ -80,7 +80,7 @@ django_checks() {
search_index() {
local -r index_version=1
local -r index_version=4
local -r index_version_file=${DATA_DIR}/.index_version
if [[ (! -f "${index_version_file}") || $(<"${index_version_file}") != "$index_version" ]]; then

View File

@@ -3,5 +3,10 @@
echo "Checking if we should start flower..."
if [[ -n "${PAPERLESS_ENABLE_FLOWER}" ]]; then
celery --app paperless flower
# Small delay to allow celery to be up first
echo "Starting flower in 5s"
sleep 5
celery --app paperless flower --conf=/usr/src/paperless/src/paperless/flowerconfig.py
else
echo "Not starting flower"
fi

View File

@@ -28,7 +28,7 @@ stderr_logfile_maxbytes=0
[program:celery]
command = celery --app paperless worker --loglevel INFO
command = celery --app paperless worker --loglevel INFO --without-mingle --without-gossip
user=paperless
stopasgroup = true
stopwaitsecs = 60

View File

@@ -18,7 +18,7 @@ if __name__ == "__main__":
REDIS_URL: Final[str] = os.getenv("PAPERLESS_REDIS", "redis://localhost:6379")
print(f"Waiting for Redis...", flush=True)
print("Waiting for Redis...", flush=True)
attempt = 0
with Redis.from_url(url=REDIS_URL) as client:
@@ -37,8 +37,8 @@ if __name__ == "__main__":
attempt += 1
if attempt >= MAX_RETRY_COUNT:
print(f"Failed to connect to redis using environment variable PAPERLESS_REDIS.")
print("Failed to connect to redis using environment variable PAPERLESS_REDIS.")
sys.exit(os.EX_UNAVAILABLE)
else:
print(f"Connected to Redis broker.")
print("Connected to Redis broker.")
sys.exit(os.EX_OK)

View File

@@ -98,7 +98,7 @@ the background.
won't automatically update to newer versions. In order to enable
updates as described above, either get the new `docker-compose.yml`
file from
[here](https://github.com/paperless-ngx/paperless-ngx/tree/master/docker/compose)
[here](https://github.com/paperless-ngx/paperless-ngx/tree/main/docker/compose)
or edit the `docker-compose.yml` file, find the line that says
```
@@ -475,12 +475,13 @@ mail_fetcher
The command takes no arguments and processes all your mail accounts and
rules.
!!! note
!!! tip
As of October 2022 Microsoft no longer supports IMAP authentication
for Exchange servers, thus Exchange is no longer supported until a
solution is implemented in the Python IMAP library used by Paperless.
See [learn.microsoft.com](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online)
To use OAuth access tokens for mail fetching,
select the box to indicate the password is actually
a token when creating or editing a mail account. The
details for creating a token depend on your email
provider.
### Creating archived documents {#archiver}

View File

@@ -9,7 +9,7 @@ Paperless will compare the matching algorithms defined by every tag,
correspondent, document type, and storage path in your database to see
if they apply to the text in a document. In other words, if you define a
tag called `Home Utility` that had a `match` property of `bc hydro` and
a `matching_algorithm` of `literal`, Paperless will automatically tag
a `matching_algorithm` of `Exact`, Paperless will automatically tag
your newly-consumed document with your `Home Utility` tag so long as the
text `bc hydro` appears in the body of the document somewhere.
@@ -25,12 +25,13 @@ documents.
The following algorithms are available:
- **None:** No matching will be performed.
- **Any:** Looks for any occurrence of any word provided in match in
the PDF. If you define the match as `Bank1 Bank2`, it will match
documents containing either of these terms.
- **All:** Requires that every word provided appears in the PDF,
albeit not in the order provided.
- **Literal:** Matches only if the match appears exactly as provided
- **Exact:** Matches only if the match appears exactly as provided
(i.e. preserve ordering) in the PDF.
- **Regular expression:** Parses the match as a regular expression and
tries to find a match within the document.
@@ -121,7 +122,17 @@ Executed after the consumer sees a new document in the consumption
folder, but before any processing of the document is performed. This
script can access the following relevant environment variables set:
- `DOCUMENT_SOURCE_PATH`
| Environment Variable | Description |
| ----------------------- | ------------------------------------------------------------ |
| `DOCUMENT_SOURCE_PATH` | Original path of the consumed document |
| `DOCUMENT_WORKING_PATH` | Path to a copy of the original that consumption will work on |
!!! note
Pre-consume scripts which modify the document should only change
the `DOCUMENT_WORKING_PATH` file or a second consume task may
be triggered, leading to failures as two tasks work on the
same document path
A simple but common example for this would be creating a simple script
like this:
@@ -130,7 +141,7 @@ like this:
```bash
#!/usr/bin/env bash
pdf2pdfocr.py -i ${DOCUMENT_SOURCE_PATH}
pdf2pdfocr.py -i ${DOCUMENT_WORKING_PATH}
```
`/etc/paperless.conf`
@@ -157,26 +168,36 @@ Executed after the consumer has successfully processed a document and
has moved it into paperless. It receives the following environment
variables:
- `DOCUMENT_ID`
- `DOCUMENT_FILE_NAME`
- `DOCUMENT_CREATED`
- `DOCUMENT_MODIFIED`
- `DOCUMENT_ADDED`
- `DOCUMENT_SOURCE_PATH`
- `DOCUMENT_ARCHIVE_PATH`
- `DOCUMENT_THUMBNAIL_PATH`
- `DOCUMENT_DOWNLOAD_URL`
- `DOCUMENT_THUMBNAIL_URL`
- `DOCUMENT_CORRESPONDENT`
- `DOCUMENT_TAGS`
- `DOCUMENT_ORIGINAL_FILENAME`
| Environment Variable | Description |
| ---------------------------- | --------------------------------------------- |
| `DOCUMENT_ID` | Database primary key of the document |
| `DOCUMENT_FILE_NAME` | Formatted filename, not including paths |
| `DOCUMENT_CREATED` | Date & time when document created |
| `DOCUMENT_MODIFIED` | Date & time when document was last modified |
| `DOCUMENT_ADDED` | Date & time when document was added |
| `DOCUMENT_SOURCE_PATH` | Path to the original document file |
| `DOCUMENT_ARCHIVE_PATH` | Path to the generate archive file (if any) |
| `DOCUMENT_THUMBNAIL_PATH` | Path to the generated thumbnail |
| `DOCUMENT_DOWNLOAD_URL` | URL for document download |
| `DOCUMENT_THUMBNAIL_URL` | URL for the document thumbnail |
| `DOCUMENT_CORRESPONDENT` | Assigned correspondent (if any) |
| `DOCUMENT_TAGS` | Comma separated list of tags applied (if any) |
| `DOCUMENT_ORIGINAL_FILENAME` | Filename of original document |
The script can be in any language, but for a simple shell script
example, you can take a look at
[post-consumption-example.sh](https://github.com/paperless-ngx/paperless-ngx/blob/main/scripts/post-consumption-example.sh)
in this project.
The script can be in any language, A simple shell script example:
The post consumption script cannot cancel the consumption process.
```bash title="post-consumption-example"
--8<-- "./scripts/post-consumption-example.sh"
```
!!! note
The post consumption script cannot cancel the consumption process.
!!! warning
The post consumption script should not modify the document files
directly
The script's stdout and stderr will be logged line by line to the
webserver log, along with the exit code of the script.
@@ -288,6 +309,8 @@ Paperless provides the following placeholders within filenames:
- `{added_month_name_short}`: Month added abbreviated name, as per
locale
- `{added_day}`: Day added only (number 01-31).
- `{owner_username}`: Username of document owner, if any, or "none"
- `{original_name}`: Document original filename, minus the extension, if any, or "none"
Paperless will try to conserve the information from your database as
much as possible. However, some characters that you can use in document
@@ -348,7 +371,7 @@ value.
One of the best things in Paperless is that you can not only access the
documents via the web interface, but also via the file system.
When as single storage layout is not sufficient for your use case,
When a single storage layout is not sufficient for your use case,
storage paths come to the rescue. Storage paths allow you to configure
more precisely where each document is stored in the file system.
@@ -394,13 +417,6 @@ structure as in the previous example above.
Defining a storage path is optional. If no storage path is defined for a
document, the global `PAPERLESS_FILENAME_FORMAT` is applied.
!!! warning
If you adjust the format of an existing storage path, old documents
don't get relocated automatically. You need to run the
[document renamer](/administration#renamer) to
adjust their paths.
## Celery Monitoring {#celery-monitoring}
The monitoring tool
@@ -481,3 +497,49 @@ You can also set the default for new tables (this does NOT affect
existing tables) with:
`ALTER DATABASE <db_name> CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;`
!!! warning
Using mariadb version 10.4+ is recommended. Using the `utf8mb3` character set on
an older system may fix issues that can arise while setting up Paperless-ngx but
`utf8mb3` can cause issues with consumption (where `utf8mb4` does not).
## Barcodes {#barcodes}
Paperless is able to utilize barcodes for automatically preforming some tasks.
At this time, the library utilized for detection of bacodes supports the following types:
- AN-13/UPC-A
- UPC-E
- EAN-8
- Code 128
- Code 93
- Code 39
- Codabar
- Interleaved 2 of 5
- QR Code
- SQ Code
You may check for updates on the [zbar library homepage](https://github.com/mchehab/zbar).
For usage in Paperless, the type of barcode does not matter, only the contents of it.
For how to enable barcode usage, see [the configuration](/configuration#barcodes).
The two settings may be enabled independently, but do have interactions as explained
below.
### Document Splitting
When enabled, Paperless will look for a barcode with the configured value and create a new document
starting from the next page. The page with the barcode on it will _not_ be retained. It
is expected to be a page existing only for triggering the split.
### Archive Serial Number Assignment
When enabled, the value of the barcode (as an integer) will be used to set the document's
archive serial number, allowing quick reference back to the original, paper document.
If document splitting via barcode is also enabled, documents will be split when an ASN
barcode is located. However, differing from the splitting, the page with the
barcode _will_ be retained. This allows application of a barcode to any page, including
one which holds data to keep in the document.

View File

@@ -16,6 +16,8 @@ The API provides 7 main endpoints:
- `/api/tags/`: Full CRUD support.
- `/api/mail_accounts/`: Full CRUD support.
- `/api/mail_rules/`: Full CRUD support.
- `/api/users/`: Full CRUD support.
- `/api/groups/`: Full CRUD support.
All of these endpoints except for the logging endpoint allow you to
fetch, edit and delete individual objects by appending their primary key
@@ -254,11 +256,15 @@ The endpoint supports the following optional form fields:
- `document_type`: Similar to correspondent.
- `tags`: Similar to correspondent. Specify this multiple times to
have multiple tags added to the document.
- `owner`: An optional user ID to set as the owner.
- `archive_serial_number`: An optional archive serial number to set.
The endpoint will immediately return "OK" if the document consumption
process was started successfully. No additional status information about
the consumption process itself is available, since that happens in a
different process.
The endpoint will immediately return HTTP 200 if the document consumption
process was started successfully, with the UUID of the consumption task
as the data. No additional status information about
the consumption process itself is available immediately, since that happens in a
different process. Querying the tasks endpoint with the returned UUID will
provide information on the state of the consumption.
## API Versioning

Binary file not shown.

Before

Width:  |  Height:  |  Size: 436 KiB

After

Width:  |  Height:  |  Size: 890 KiB

View File

@@ -1,5 +1,99 @@
# Changelog
## paperless-ngx 1.13.0
### Features
- Feature: allow disable warn on close saved view with changes [@shamoon](https://github.com/shamoon) ([#2681](https://github.com/paperless-ngx/paperless-ngx/pull/2681))
- Feature: Add option to enable response compression [@stumpylog](https://github.com/stumpylog) ([#2621](https://github.com/paperless-ngx/paperless-ngx/pull/2621))
- Feature: split documents on ASN barcode [@muued](https://github.com/muued) ([#2554](https://github.com/paperless-ngx/paperless-ngx/pull/2554))
### Bug Fixes
- Fix: Ignore path filtering didn't handle sub directories [@stumpylog](https://github.com/stumpylog) ([#2674](https://github.com/paperless-ngx/paperless-ngx/pull/2674))
- Bugfix: Generation of secret key hangs during install script [@stumpylog](https://github.com/stumpylog) ([#2657](https://github.com/paperless-ngx/paperless-ngx/pull/2657))
- Fix: Remove files produced by barcode splitting when completed [@stumpylog](https://github.com/stumpylog) ([#2648](https://github.com/paperless-ngx/paperless-ngx/pull/2648))
- Fix: add missing storage path placeholders [@shamoon](https://github.com/shamoon) ([#2651](https://github.com/paperless-ngx/paperless-ngx/pull/2651))
- Fix long dropdown contents break document detail column view [@shamoon](https://github.com/shamoon) ([#2638](https://github.com/paperless-ngx/paperless-ngx/pull/2638))
- Fix: tags dropdown should stay closed when removing [@shamoon](https://github.com/shamoon) ([#2625](https://github.com/paperless-ngx/paperless-ngx/pull/2625))
- Bugfix: Configure scheduled tasks to expire after some time [@stumpylog](https://github.com/stumpylog) ([#2614](https://github.com/paperless-ngx/paperless-ngx/pull/2614))
- Bugfix: Limit management list pagination maxSize to 5 [@Kaaybi](https://github.com/Kaaybi) ([#2618](https://github.com/paperless-ngx/paperless-ngx/pull/2618))
- Fix: Don't crash on bad ASNs during indexing [@stumpylog](https://github.com/stumpylog) ([#2586](https://github.com/paperless-ngx/paperless-ngx/pull/2586))
- Fix: Prevent mktime OverflowError except in even more rare caes [@stumpylog](https://github.com/stumpylog) ([#2574](https://github.com/paperless-ngx/paperless-ngx/pull/2574))
- Bugfix: Whoosh relative date queries weren't handling timezones [@stumpylog](https://github.com/stumpylog) ([#2566](https://github.com/paperless-ngx/paperless-ngx/pull/2566))
- Fix importing files with non-ascii names [@Kexogg](https://github.com/Kexogg) ([#2555](https://github.com/paperless-ngx/paperless-ngx/pull/2555))
### Documentation
- Chore: update recommended Gotenberg to 7.8, docs note possible incompatibility [@shamoon](https://github.com/shamoon) ([#2608](https://github.com/paperless-ngx/paperless-ngx/pull/2608))
- [Documentation] Add v1.12.2 changelog [@github-actions](https://github.com/github-actions) ([#2553](https://github.com/paperless-ngx/paperless-ngx/pull/2553))
### Maintenance
- Chore: Faster Docker image cleanup [@stumpylog](https://github.com/stumpylog) ([#2687](https://github.com/paperless-ngx/paperless-ngx/pull/2687))
- Chore: Remove duplicated folder [@stumpylog](https://github.com/stumpylog) ([#2561](https://github.com/paperless-ngx/paperless-ngx/pull/2561))
- Chore: Switch test coverage to Codecov [@stumpylog](https://github.com/stumpylog) ([#2582](https://github.com/paperless-ngx/paperless-ngx/pull/2582))
- Bump docker/build-push-action from 3 to 4 [@dependabot](https://github.com/dependabot) ([#2576](https://github.com/paperless-ngx/paperless-ngx/pull/2576))
- Chore: Run tests which require convert in the CI [@stumpylog](https://github.com/stumpylog) ([#2570](https://github.com/paperless-ngx/paperless-ngx/pull/2570))
- Feature: split documents on ASN barcode [@muued](https://github.com/muued) ([#2554](https://github.com/paperless-ngx/paperless-ngx/pull/2554))
- Bugfix: Whoosh relative date queries weren't handling timezones [@stumpylog](https://github.com/stumpylog) ([#2566](https://github.com/paperless-ngx/paperless-ngx/pull/2566))
- Fix importing files with non-ascii names [@Kexogg](https://github.com/Kexogg) ([#2555](https://github.com/paperless-ngx/paperless-ngx/pull/2555))
## paperless-ngx 1.12.2
_Note: Version 1.12.x introduced searching of comments which will work for comments added after the upgrade but a reindex of the search index is required in order to be able to search
older comments. The Docker image will automatically perform this reindex, bare metal installations will have to perform this manually, see [the docs](https://docs.paperless-ngx.com/administration/#index)._
### Bug Fixes
- Bugfix: Allow pre-consume scripts to modify incoming file [@stumpylog](https://github.com/stumpylog) ([#2547](https://github.com/paperless-ngx/paperless-ngx/pull/2547))
- Bugfix: Return to page based barcode scanning [@stumpylog](https://github.com/stumpylog) ([#2544](https://github.com/paperless-ngx/paperless-ngx/pull/2544))
- Fix: Try to prevent title debounce overwriting [@shamoon](https://github.com/shamoon) ([#2543](https://github.com/paperless-ngx/paperless-ngx/pull/2543))
- Fix comment search highlight + multi-word search [@shamoon](https://github.com/shamoon) ([#2542](https://github.com/paperless-ngx/paperless-ngx/pull/2542))
- Bugfix: Request PDF/A format from Gotenberg [@stumpylog](https://github.com/stumpylog) ([#2530](https://github.com/paperless-ngx/paperless-ngx/pull/2530))
- Fix: Trigger reindex for pre-existing comments [@shamoon](https://github.com/shamoon) ([#2519](https://github.com/paperless-ngx/paperless-ngx/pull/2519))
### Documentation
- Bugfix: Allow pre-consume scripts to modify incoming file [@stumpylog](https://github.com/stumpylog) ([#2547](https://github.com/paperless-ngx/paperless-ngx/pull/2547))
- Fix: Trigger reindex for pre-existing comments [@shamoon](https://github.com/shamoon) ([#2519](https://github.com/paperless-ngx/paperless-ngx/pull/2519))
- Minor updates to development documentation [@clemensrieder](https://github.com/clemensrieder) ([#2474](https://github.com/paperless-ngx/paperless-ngx/pull/2474))
- [Documentation] Add v1.12.1 changelog [@github-actions](https://github.com/github-actions) ([#2515](https://github.com/paperless-ngx/paperless-ngx/pull/2515))
### Maintenance
- Chore: Fix tag cleaner to work with attestations [@stumpylog](https://github.com/stumpylog) ([#2532](https://github.com/paperless-ngx/paperless-ngx/pull/2532))
- Chore: Make installers statically versioned [@stumpylog](https://github.com/stumpylog) ([#2517](https://github.com/paperless-ngx/paperless-ngx/pull/2517))
### All App Changes
- Bugfix: Allow pre-consume scripts to modify incoming file [@stumpylog](https://github.com/stumpylog) ([#2547](https://github.com/paperless-ngx/paperless-ngx/pull/2547))
- Bugfix: Return to page based barcode scanning [@stumpylog](https://github.com/stumpylog) ([#2544](https://github.com/paperless-ngx/paperless-ngx/pull/2544))
- Fix: Try to prevent title debounce overwriting [@shamoon](https://github.com/shamoon) ([#2543](https://github.com/paperless-ngx/paperless-ngx/pull/2543))
- Fix comment search highlight + multi-word search [@shamoon](https://github.com/shamoon) ([#2542](https://github.com/paperless-ngx/paperless-ngx/pull/2542))
- Bugfix: Request PDF/A format from Gotenberg [@stumpylog](https://github.com/stumpylog) ([#2530](https://github.com/paperless-ngx/paperless-ngx/pull/2530))
## paperless-ngx 1.12.1
### Bug Fixes
- Fix: comments not showing in search until after manual reindex in v1.12 [@shamoon](https://github.com/shamoon) ([#2513](https://github.com/paperless-ngx/paperless-ngx/pull/2513))
- Fix: date range search broken in 1.12 [@shamoon](https://github.com/shamoon) ([#2509](https://github.com/paperless-ngx/paperless-ngx/pull/2509))
### Documentation
- [Documentation] Add v1.12.0 changelog [@github-actions](https://github.com/github-actions) ([#2507](https://github.com/paperless-ngx/paperless-ngx/pull/2507))
### Maintenance
- Moves back to the main release-drafter now that it does what we wanted [@stumpylog](https://github.com/stumpylog) ([#2503](https://github.com/paperless-ngx/paperless-ngx/pull/2503))
### All App Changes
- Fix: comments not showing in search until after manual reindex in v1.12 [@shamoon](https://github.com/shamoon) ([#2513](https://github.com/paperless-ngx/paperless-ngx/pull/2513))
- Fix: date range search broken in 1.12 [@shamoon](https://github.com/shamoon) ([#2509](https://github.com/paperless-ngx/paperless-ngx/pull/2509))
## paperless-ngx 1.12.0
### Features

View File

@@ -17,6 +17,8 @@ run paperless, these settings have to be defined in different places.
## Required services
### Redis Broker
`PAPERLESS_REDIS=<url>`
: This is required for processing scheduled tasks such as email
@@ -33,6 +35,8 @@ matcher.
Defaults to `redis://localhost:6379`.
### Database
`PAPERLESS_DBENGINE=<engine_name>`
: Optional, gives the ability to choose Postgres or MariaDB for
@@ -86,6 +90,36 @@ changed here.
Default is `prefer`.
`PAPERLESS_DBSSLROOTCERT=<ca-path>`
: SSL root certificate path
See [the official documentation about
sslmode](https://www.postgresql.org/docs/current/libpq-ssl.html).
Changes path of `root.crt`.
Defaults to unset, using the documented path in the home directory.
`PAPERLESS_DBSSLCERT=<client-cert-path>`
: SSL client certificate path
See [the official documentation about
sslmode](https://www.postgresql.org/docs/current/libpq-ssl.html).
Changes path of `postgresql.crt`.
Defaults to unset, using the documented path in the home directory.
`PAPERLESS_DBSSLKEY=<client-cert-key>`
: SSL client key path
See [the official documentation about
sslmode](https://www.postgresql.org/docs/current/libpq-ssl.html).
Changes path of `postgresql.key`.
Defaults to unset, using the documented path in the home directory.
`PAPERLESS_DB_TIMEOUT=<float>`
: Amount of time for a database connection to wait for the database to
@@ -94,6 +128,47 @@ changing to postgresql if you need to increase this.
Defaults to unset, keeping the Django defaults.
## Optional Services
### Tika {#tika}
Paperless can make use of [Tika](https://tika.apache.org/) and
[Gotenberg](https://gotenberg.dev/) for parsing and converting
"Office" documents (such as ".doc", ".xlsx" and ".odt").
Tika and Gotenberg are also needed to allow parsing of E-Mails (.eml).
If you wish to use this, you must provide a Tika server and a Gotenberg server,
configure their endpoints, and enable the feature.
`PAPERLESS_TIKA_ENABLED=<bool>`
: Enable (or disable) the Tika parser.
Defaults to false.
`PAPERLESS_TIKA_ENDPOINT=<url>`
: Set the endpoint URL were Paperless can reach your Tika server.
Defaults to "<http://localhost:9998>".
`PAPERLESS_TIKA_GOTENBERG_ENDPOINT=<url>`
: Set the endpoint URL were Paperless can reach your Gotenberg server.
Defaults to "<http://localhost:3000>".
If you run paperless on docker, you can add those services to the
docker-compose file (see the provided
[`docker-compose.sqlite-tika.yml`](https://github.com/paperless-ngx/paperless-ngx/blob/main/docker/compose/docker-compose.sqlite-tika.yml)
file for reference).
Add all three configuration parameters to your configuration. If using
Docker, this may be the `environment` key of the webserver or a
`docker-compose.env` file. Bare metal installations may have a `.conf` file
containing the configuration parameters. Be sure to use the correct format
and watch out for indentation if editing the YAML file.
## Paths and folders
`PAPERLESS_CONSUMPTION_DIR=<path>`
@@ -141,7 +216,8 @@ directory.
files created using "collectstatic" manager command are stored.
Unless you're doing something fancy, there is no need to override
this.
this. If this is changed, you may need to run
`collectstatic` again.
Defaults to "../static/", relative to the "src" directory.
@@ -226,8 +302,7 @@ not include a trailing slash. E.g. <https://paperless.domain.com>
: A list of trusted origins for unsafe requests (e.g. POST). As of
Django 4.0 this is required to access the Django admin via the web.
See
<https://docs.djangoproject.com/en/4.0/ref/settings/#csrf-trusted-origins>
See the [Django project documentation on the settings](https://docs.djangoproject.com/en/4.1/ref/settings/#csrf-trusted-origins)
Can also be set using PAPERLESS_URL (see above).
@@ -238,8 +313,8 @@ See
: If you're planning on putting Paperless on the open internet, then
you really should set this value to the domain name you're using.
Failing to do so leaves you open to HTTP host header attacks:
<https://docs.djangoproject.com/en/3.1/topics/security/#host-header-validation>
Failing to do so leaves you open to HTTP host header attacks.
You can read more about this in [the Django project's documentation](https://docs.djangoproject.com/en/4.1/topics/security/#host-header-validation)
Just remember that this is a comma-separated list, so
"example.com" is fine, as is "example.com,www.example.com", but
@@ -261,6 +336,14 @@ do CORS calls. Set this to your public domain name.
Defaults to "<http://localhost:8000>".
`PAPERLESS_TRUSTED_PROXIES=<comma-separated-list>`
: This may be needed to prevent IP address spoofing if you are using e.g.
fail2ban with log entries for failed authorization attempts. Value should be
IP address(es).
Defaults to empty string.
`PAPERLESS_FORCE_SCRIPT_NAME=<path>`
: To host paperless under a subpath url like example.com/paperless you
@@ -347,16 +430,16 @@ applications.
If you're exposing paperless to the internet directly, do not use
this.
Also see the warning [in the official documentation](https://docs.djangoproject.com/en/3.1/howto/auth-remote-user/#configuration).
Also see the warning [in the official documentation](https://docs.djangoproject.com/en/4.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
: 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).
[HttpRequest.META](https://docs.djangoproject.com/en/4.1/ref/request-response/#django.http.HttpRequest.META).
Thus, the configured value must start with `HTTP*`
followed by the normalized actual header name.
@@ -382,21 +465,20 @@ needs.
: Customize the language that paperless will attempt to use when
parsing documents.
It should be a 3-letter language code consistent with ISO 639:
https://www.loc.gov/standards/iso639-2/php/code_list.php
It should be a 3-letter code, see the list of [languages Tesseract supports](https://tesseract-ocr.github.io/tessdoc/Data-Files-in-different-versions.html).
Set this to the language most of your documents are written in.
This can be a combination of multiple languages such as `deu+eng`,
in which case tesseract will use whatever language matches best.
Keep in mind that tesseract uses much more cpu time with multiple
in which case Tesseract will use whatever language matches best.
Keep in mind that Tesseract uses much more CPU time with multiple
languages enabled.
Defaults to "eng".
!!! note
If your language contains a '-' such as chi-sim, you must use chi_sim
If your language contains a '-' such as chi-sim, you must use `chi_sim`.
`PAPERLESS_OCR_MODE=<mode>`
@@ -406,12 +488,6 @@ modes are available:
- `skip`: Paperless skips all pages and will perform ocr only on
pages where no text is present. This is the safest option.
- `skip_noarchive`: In addition to skip, paperless won't create
an archived version of your documents when it finds any text in
them. This is useful if you don't want to have two
almost-identical versions of your digital documents in the media
folder. This is the fastest option.
- `redo`: Paperless will OCR all pages of your documents and
attempt to replace any existing text layers with new text. This
will be useful for documents from scanners that already
@@ -434,6 +510,19 @@ modes are available:
Read more about this in the [OCRmyPDF
documentation](https://ocrmypdf.readthedocs.io/en/latest/advanced.html#when-ocr-is-skipped).
`PAPERLESS_OCR_SKIP_ARCHIVE_FILE=<mode>`
: Specify when you would like paperless to skip creating an archived
version of your documents. This is useful if you don't want to have two
almost-identical versions of your documents in the media folder.
- `never`: Never skip creating an archived version.
- `with_text`: Skip creating an archived version for documents
that already have embedded text.
- `always`: Always skip creating an archived version.
The default is `never`.
`PAPERLESS_OCR_CLEAN=<mode>`
: Tells paperless to use `unpaper` to clean any input document before
@@ -576,76 +665,6 @@ they use underscores instead of dashes.
{"deskew": true, "optimize": 3, "unpaper_args": "--pre-rotate 90"}
```
## Tika settings {#tika}
Paperless can make use of [Tika](https://tika.apache.org/) and
[Gotenberg](https://gotenberg.dev/) for parsing and converting
"Office" documents (such as ".doc", ".xlsx" and ".odt").
Tika and Gotenberg are also needed to allow parsing of E-Mails (.eml).
If you wish to use this, you must provide a Tika server and a Gotenberg server,
configure their endpoints, and enable the feature.
`PAPERLESS_TIKA_ENABLED=<bool>`
: Enable (or disable) the Tika parser.
Defaults to false.
`PAPERLESS_TIKA_ENDPOINT=<url>`
: Set the endpoint URL were Paperless can reach your Tika server.
Defaults to "<http://localhost:9998>".
`PAPERLESS_TIKA_GOTENBERG_ENDPOINT=<url>`
: Set the endpoint URL were Paperless can reach your Gotenberg server.
Defaults to "<http://localhost:3000>".
If you run paperless on docker, you can add those services to the
docker-compose file (see the provided `docker-compose.sqlite-tika.yml`
file for reference). The changes requires are as follows:
```yaml
services:
# ...
webserver:
# ...
environment:
# ...
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
# ...
gotenberg:
image: gotenberg/gotenberg:7.6
restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not
# want to allow external content like tracking pixels or even javascript.
command:
- 'gotenberg'
- '--chromium-disable-javascript=true'
- '--chromium-allow-list=file:///tmp/.*'
tika:
image: ghcr.io/paperless-ngx/tika:latest
restart: unless-stopped
```
Add the configuration variables to the environment of the webserver
(alternatively put the configuration in the `docker-compose.env` file)
and add the additional services below the webserver service. Watch out
for indentation.
Make sure to use the correct format `PAPERLESS_TIKA_ENABLED = 1` so python_dotenv can parse the statement correctly.
## Software tweaks {#software_tweaks}
`PAPERLESS_TASK_WORKERS=<num>`
@@ -697,17 +716,10 @@ paperless will process in parallel on a single document.
on large documents within the default 1800 seconds. So extending
this timeout may prove to be useful on weak hardware setups.
`PAPERLESS_WORKER_RETRY=<num>`
: If PAPERLESS_WORKER_TIMEOUT has been configured, the retry time for
a task can also be configured. By default, this value will be set to
10s more than the worker timeout. This value should never be set
less than the worker timeout.
`PAPERLESS_TIME_ZONE=<timezone>`
: Set the time zone here. See
<https://docs.djangoproject.com/en/3.1/ref/settings/#std:setting-TIME_ZONE>
: Set the time zone here. See more details on
why and how to set it [in the Django project documentation](https://docs.djangoproject.com/en/4.1/ref/settings/#std:setting-TIME_ZONE)
for details on how to set it.
Defaults to UTC.
@@ -757,46 +769,45 @@ should be a valid crontab(5) expression describing when to run.
Defaults to `30 0 * * sun` or Sunday at 30 minutes past midnight.
## Polling {#polling}
`PAPERLESS_ENABLE_COMPRESSION=<bool>`
`PAPERLESS_CONSUMER_POLLING=<num>`
: Enables compression of the responses from the webserver.
: If paperless won't find documents added to your consume folder, it
might not be able to automatically detect filesystem changes. In
that case, specify a polling interval in seconds here, which will
then cause paperless to periodically check your consumption
directory for changes. This will also disable listening for file
system changes with `inotify`.
: Defaults to 1, enabling compression.
Defaults to 0, which disables polling and uses filesystem
notifications.
!!! note
`PAPERLESS_CONSUMER_POLLING_RETRY_COUNT=<num>`
If you are using a proxy such as nginx, it is likely more efficient
to enable compression in your proxy configuration rather than
the webserver
: If consumer polling is enabled, sets the number of times paperless
will check for a file to remain unmodified.
`PAPERLESS_CONVERT_MEMORY_LIMIT=<num>`
Defaults to 5.
: On smaller systems, or even in the case of Very Large Documents, the
consumer may explode, complaining about how it's "unable to extend
pixel cache". In such cases, try setting this to a reasonably low
value, like 32. The default is to use whatever is necessary to do
everything without writing to disk, and units are in megabytes.
`PAPERLESS_CONSUMER_POLLING_DELAY=<num>`
For more information on how to use this value, you should search the
web for "MAGICK_MEMORY_LIMIT".
: If consumer polling is enabled, sets the delay in seconds between
each check (above) paperless will do while waiting for a file to
remain unmodified.
Defaults to 0, which disables the limit.
Defaults to 5.
`PAPERLESS_CONVERT_TMPDIR=<path>`
## iNotify {#inotify}
: Similar to the memory limit, if you've got a small system and your
OS mounts /tmp as tmpfs, you should set this to a path that's on a
physical disk, like /home/your_user/tmp or something. ImageMagick
will use this as scratch space when crunching through very large
documents.
`PAPERLESS_CONSUMER_INOTIFY_DELAY=<num>`
For more information on how to use this value, you should search the
web for "MAGICK_TMPDIR".
: Sets the time in seconds the consumer will wait for additional
events from inotify before the consumer will consider a file ready
and begin consumption. Certain scanners or network setups may
generate multiple events for a single file, leading to multiple
consumers working on the same file. Configure this to prevent that.
Default is none, which disables the temporary directory.
Defaults to 0.5 seconds.
## Document Consumption {#consume_config}
`PAPERLESS_CONSUMER_DELETE_DUPLICATES=<bool>`
@@ -827,96 +838,51 @@ don't exist yet.
Defaults to false.
`PAPERLESS_CONSUMER_ENABLE_BARCODES=<bool>`
`PAPERLESS_CONSUMER_IGNORE_PATTERNS=<json>`
: Enables the scanning and page separation based on detected barcodes.
This allows for scanning and adding multiple documents per uploaded
file, which are separated by one or multiple barcode pages.
: By default, paperless ignores certain files and folders in the
consumption directory, such as system files created by the Mac OS
or hidden folders some tools use to store data.
For ease of use, it is suggested to use a standardized separation
page, e.g. [here](https://www.alliancegroup.co.uk/patch-codes.htm).
This can be adjusted by configuring a custom json array with
patterns to exclude.
If no barcodes are detected in the uploaded file, no page separation
will happen.
For example, `.DS_STORE/*` will ignore any files found in a folder
named `.DS_STORE`, including `.DS_STORE/bar.pdf` and `foo/.DS_STORE/bar.pdf`
The original document will be removed and the separated pages will
be saved as pdf.
A pattern like `._*` will ignore anything starting with `._`, including:
`._foo.pdf` and `._bar/foo.pdf`
Defaults to false.
Defaults to
`[".DS_STORE/*", "._*", ".stfolder/*", ".stversions/*", ".localized/*", "desktop.ini", "@eaDir/*"]`.
`PAPERLESS_CONSUMER_BARCODE_TIFF_SUPPORT=<bool>`
`PAPERLESS_CONSUMER_BARCODE_SCANNER=<string>`
: Whether TIFF image files should be scanned for barcodes. This will
automatically convert any TIFF image(s) to pdfs for later
processing. This only has an effect, if
PAPERLESS_CONSUMER_ENABLE_BARCODES has been enabled.
: Sets the barcode scanner used for barcode functionality.
Defaults to false.
Currently, "PYZBAR" (the default) or "ZXING" might be selected.
If you have problems that your Barcodes/QR-Codes are not detected
(especially with bad scan quality and/or small codes), try the other one.
`PAPERLESS_CONSUMER_BARCODE_STRING=PATCHT`
zxing is not available on all platforms.
: Defines the string to be detected as a separator barcode. If
paperless is used with the PATCH-T separator pages, users shouldn't
change this.
`PAPERLESS_PRE_CONSUME_SCRIPT=<filename>`
Defaults to "PATCHT"
: After some initial validation, Paperless can trigger an arbitrary
script if you like before beginning consumption. This script will be provided
data for it to work with via the environment.
`PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE=<bool>`
For more information, take a look at [pre-consumption script](/advanced_usage#pre-consume-script).
: Enables the detection of barcodes in the scanned document and
setting the ASN (archive serial number) if a properly formatted
barcode is detected.
The barcode must consist of a (configurable) prefix and the ASN
to be set, for instance `ASN00123`.
This option is compatible with barcode page separation, since
pages will be split up before reading the ASN.
If no ASN barcodes are detected in the uploaded file, no ASN will
be set. If a barcode with an already existing ASN is detected, no ASN
will be set either and a warning will be logged.
Defaults to false.
`PAPERLESS_CONSUMER_ASN_BARCODE_PREFIX=ASN`
: Defines the prefix that is used to identify a barcode as an ASN
barcode.
Defaults to "ASN"
`PAPERLESS_CONVERT_MEMORY_LIMIT=<num>`
: On smaller systems, or even in the case of Very Large Documents, the
consumer may explode, complaining about how it's "unable to extend
pixel cache". In such cases, try setting this to a reasonably low
value, like 32. The default is to use whatever is necessary to do
everything without writing to disk, and units are in megabytes.
For more information on how to use this value, you should search the
web for "MAGICK_MEMORY_LIMIT".
Defaults to 0, which disables the limit.
`PAPERLESS_CONVERT_TMPDIR=<path>`
: Similar to the memory limit, if you've got a small system and your
OS mounts /tmp as tmpfs, you should set this to a path that's on a
physical disk, like /home/your_user/tmp or something. ImageMagick
will use this as scratch space when crunching through very large
documents.
For more information on how to use this value, you should search the
web for "MAGICK_TMPDIR".
Default is none, which disables the temporary directory.
The default is blank, which means nothing will be executed.
`PAPERLESS_POST_CONSUME_SCRIPT=<filename>`
: After a document is consumed, Paperless can trigger an arbitrary
script if you like. This script will be passed a number of arguments
for you to work with. For more information, take a look at [Post-consumption script](/advanced_usage#post-consume-script).
script if you like. This script will be provided
data for it to work with via the environment.
For more information, take a look at [Post-consumption script](/advanced_usage#post-consume-script).
The default is blank, which means nothing will be executed.
@@ -983,16 +949,109 @@ within your documents.
second, and year last order. Characters D, M, or Y can be shuffled
to meet the required order.
`PAPERLESS_CONSUMER_IGNORE_PATTERNS=<json>`
### Polling {#polling}
: By default, paperless ignores certain files and folders in the
consumption directory, such as system files created by the Mac OS.
`PAPERLESS_CONSUMER_POLLING=<num>`
This can be adjusted by configuring a custom json array with
patterns to exclude.
: If paperless won't find documents added to your consume folder, it
might not be able to automatically detect filesystem changes. In
that case, specify a polling interval in seconds here, which will
then cause paperless to periodically check your consumption
directory for changes. This will also disable listening for file
system changes with `inotify`.
Defaults to
`[".DS_STORE/*", "._*", ".stfolder/*", ".stversions/*", ".localized/*", "desktop.ini"]`.
Defaults to 0, which disables polling and uses filesystem
notifications.
`PAPERLESS_CONSUMER_POLLING_RETRY_COUNT=<num>`
: If consumer polling is enabled, sets the number of times paperless
will check for a file to remain unmodified.
Defaults to 5.
`PAPERLESS_CONSUMER_POLLING_DELAY=<num>`
: If consumer polling is enabled, sets the delay in seconds between
each check (above) paperless will do while waiting for a file to
remain unmodified.
Defaults to 5.
### iNotify {#inotify}
`PAPERLESS_CONSUMER_INOTIFY_DELAY=<num>`
: Sets the time in seconds the consumer will wait for additional
events from inotify before the consumer will consider a file ready
and begin consumption. Certain scanners or network setups may
generate multiple events for a single file, leading to multiple
consumers working on the same file. Configure this to prevent that.
Defaults to 0.5 seconds.
## Barcodes {#barcodes}
`PAPERLESS_CONSUMER_ENABLE_BARCODES=<bool>`
: Enables the scanning and page separation based on detected barcodes.
This allows for scanning and adding multiple documents per uploaded
file, which are separated by one or multiple barcode pages.
For ease of use, it is suggested to use a standardized separation
page, e.g. [here](https://www.alliancegroup.co.uk/patch-codes.htm).
If no barcodes are detected in the uploaded file, no page separation
will happen.
The original document will be removed and the separated pages will
be saved as pdf.
See additional information in the [advanced usage documentation](/advanced_usage#barcodes)
Defaults to false.
`PAPERLESS_CONSUMER_BARCODE_TIFF_SUPPORT=<bool>`
: Whether TIFF image files should be scanned for barcodes. This will
automatically convert any TIFF image(s) to pdfs for later
processing. This only has an effect, if
PAPERLESS_CONSUMER_ENABLE_BARCODES has been enabled.
Defaults to false.
`PAPERLESS_CONSUMER_BARCODE_STRING=<string>`
: Defines the string to be detected as a separator barcode. If
paperless is used with the PATCH-T separator pages, users shouldn't
change this.
Defaults to "PATCHT"
`PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE=<bool>`
: Enables the detection of barcodes in the scanned document and
setting the ASN (archive serial number) if a properly formatted
barcode is detected.
The barcode must consist of a (configurable) prefix and the ASN
to be set, for instance `ASN00123`.
This option is compatible with barcode page separation, since
pages will be split up before reading the ASN.
If no ASN barcodes are detected in the uploaded file, no ASN will
be set. If a barcode with an already existing ASN is detected, no ASN
will be set either and a warning will be logged.
Defaults to false.
`PAPERLESS_CONSUMER_ASN_BARCODE_PREFIX=<string>`
: Defines the prefix that is used to identify a barcode as an ASN
barcode.
Defaults to "ASN"
## Binaries
@@ -1084,12 +1143,14 @@ actual group ID on the host system, which you can get by executing
: Additional OCR languages to install. By default, paperless comes
with English, German, Italian, Spanish and French. If your language
is not in this list, install additional languages with this
configuration option:
configuration option ([find the right LangCodes](https://tesseract-ocr.github.io/tessdoc/Data-Files-in-different-versions.html)):
``` bash
PAPERLESS_OCR_LANGUAGES=tur ces
```
Make sure it's a space separated list when using several values.
To actually use these languages, also set the default OCR language
of paperless:

View File

@@ -1,9 +1,9 @@
# Development
This section describes the steps you need to take to start development
on paperless-ngx.
on Paperless-ngx.
Check out the source from github. The repository is organized in the
Check out the source from GitHub. The repository is organized in the
following way:
- `main` always represents the latest release and will only see
@@ -12,7 +12,7 @@ following way:
- `feature-X` contain bigger changes that will be in some release, but
not necessarily the next one.
When making functional changes to paperless, _always_ make your changes
When making functional changes to Paperless-ngx, _always_ make your changes
on the `dev` branch.
Apart from that, the folder structure is as follows:
@@ -24,9 +24,9 @@ Apart from that, the folder structure is as follows:
development.
- `docker/` - Files required to build the docker image.
## Contributing to Paperless
## Contributing to Paperless-ngx
Maybe you've been using Paperless for a while and want to add a feature
Maybe you've been using Paperless-ngx 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 open source software is that you can see what's
wrong and help to get it fixed for everyone!
@@ -36,13 +36,13 @@ conduct](https://github.com/paperless-ngx/paperless-ngx/blob/main/CODE_OF_CONDUC
and other important information in the [contributing
guidelines](https://github.com/paperless-ngx/paperless-ngx/blob/main/CONTRIBUTING.md).
## Code formatting with pre-commit Hooks
## Code formatting with pre-commit hooks
To ensure a consistent style and formatting across the project source,
the project utilizes a Git [`pre-commit`](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
hook to perform some formatting and linting before a commit is allowed.
the project utilizes Git [`pre-commit`](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
hooks to perform some formatting and linting before a commit is allowed.
That way, everyone uses the same style and some common issues can be caught
early on. See below for installation instructions.
early on.
Once installed, hooks will run when you commit. If the formatting isn't
quite right or a linter catches something, the commit will be rejected.
@@ -51,129 +51,115 @@ as the Python formatting tool `black`, will format failing
files, so all you need to do is `git add` those files again
and retry your commit.
## Initial setup and first start
## General 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:
After you forked and cloned the code from GitHub you need to perform a
first-time setup.
!!! note
Every command is executed directly from the root folder of the project unless specified otherwise.
1. Install prerequisites + pipenv as mentioned in
[Bare metal route](/setup#bare_metal)
[Bare metal route](/setup#bare_metal).
2. Copy `paperless.conf.example` to `paperless.conf` and enable debug
mode.
mode within the file via `PAPERLESS_DEBUG=true`.
3. Install the Angular CLI interface:
3. Create `consume` and `media` directories:
```shell-session
$ npm install -g @angular/cli
```bash
$ mkdir -p consume media
```
4. Install pre-commit hooks
4. Install the Python dependencies:
```shell-session
pre-commit install
```bash
$ pipenv install --dev
```
5. Create `consume` and `media` folders in the cloned root folder.
!!! note
```shell-session
mkdir -p consume media
Using a virtual environment is highly recommended. You can spawn one via `pipenv shell`.
Make sure you're using Python 3.10.x or lower. Otherwise you might
get issues with building dependencies. You can use
[pyenv](https://github.com/pyenv/pyenv) to install a specific
Python version.
5. Install pre-commit hooks:
```bash
$ pre-commit install
```
6. You can now either ...
6. Apply migrations and create a superuser for your development instance:
```bash
# src/
$ python3 manage.py migrate
$ python3 manage.py createsuperuser
```
7. You can now either ...
- install redis or
- use the included scripts/start-services.sh to use docker to fire
- 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 database server) or
- spin up a bare redis container
```shell-session
docker run -d -p 6379:6379 --restart unless-stopped redis:latest
```
$ docker run -d -p 6379:6379 --restart unless-stopped redis:latest
```
7. Install the python dependencies by performing in the src/ directory.
```shell-session
pipenv install --dev
```
!!! note
Make sure you're using python 3.10.x or lower. Otherwise you might
get issues with building dependencies. You can use
[pyenv](https://github.com/pyenv/pyenv) to install a specific
python version.
8. Generate the static UI so you can perform a login to get session
that is required for frontend development (this needs to be done one
time only). From src-ui directory:
```shell-session
npm install .
./node_modules/.bin/ng build --configuration production
```
9. Apply migrations and create a superuser for your dev instance:
```shell-session
python3 manage.py migrate
python3 manage.py createsuperuser
```
10. Now spin up the dev backend. Depending on which part of paperless
you're developing for, you need to have some or all of them
running.
```shell-session
python3 manage.py runserver & python3 manage.py document_consumer & celery --app paperless worker
```
11. 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.
8. Continue with either back-end or front-end development or both :-).
## Back end development
The backend is a [Django](https://www.djangoproject.com/) application. PyCharm works well for development,
but you can use whatever you want.
The back end is a [Django](https://www.djangoproject.com/) application.
[PyCharm](https://www.jetbrains.com/de-de/pycharm/) as well as [Visual Studio Code](https://code.visualstudio.com)
work well for development, but you can use whatever you want.
Configure the IDE to use the src/ folder as the base source folder.
Configure the IDE to use the `src/`-folder as the base source folder.
Configure the following launch configurations in your IDE:
- `python3 manage.py runserver`
- `celery --app paperless worker`
- `python3 manage.py document_consumer`
- `celery --app paperless worker -l DEBUG` (or any other log level)
To start them all:
```shell-session
python3 manage.py runserver & python3 manage.py document_consumer & celery --app paperless worker
```bash
# src/
$ python3 manage.py runserver & \
python3 manage.py document_consumer & \
celery --app paperless worker -l DEBUG
```
Testing and code style:
You might need the front end to test your back end code.
This assumes that you have AngularJS installed on your system.
Go to the [Front end development](#front-end-development) section for further details.
To build the front end once use this command:
```bash
# src-ui/
$ npm install
$ ng build --configuration production
```
### Testing
- Run `pytest` in the `src/` directory to execute all tests. This also
generates a HTML coverage report. When runnings test, paperless.conf
is loaded as well. However: the tests rely on the default
generates a HTML coverage report. When runnings test, `paperless.conf`
is loaded as well. However, the tests rely on the default
configuration. This is not ideal. But for now, make sure no settings
except for DEBUG are overridden when testing.
- Coding style is enforced by the Git pre-commit hooks. These will
ensure your code is formatted and do some linting when you do a `git commit`.
- You can also run `black` manually to format your code
- The `pre-commit` hooks will modify files and interact with each other.
It may take a couple of `git add`, `git commit` cycle to satisfy them.
!!! note
The line length rule E501 is generally useful for getting multiple
@@ -184,98 +170,98 @@ Testing and code style:
## Front end development
The front end is built using Angular. In order to get started, you need
`npm`. Install the Angular CLI interface with
The front end is built using AngularJS. In order to get started, you need Node.js (version 14.15+) and
`npm`.
```shell-session
$ npm install -g @angular/cli
```
!!! note
and make sure that it's on your path. Next, in the src-ui/ directory,
install the required dependencies of the project.
The following commands are all performed in the `src-ui`-directory. You will need a running back end (including an active session) to connect to the back end API. To spin it up refer to the commands under the section [above](#back-end-development).
```shell-session
$ npm install
```
1. Install the Angular CLI. You might need sudo privileges
to perform this command:
You can launch a development server by running
```bash
$ npm install -g @angular/cli
```
```shell-session
$ ng serve
```
2. Make sure that it's on your path.
This will automatically update whenever you save. However, in-place
compilation might fail on syntax errors, in which case you need to
restart it.
3. Install all neccessary modules:
By default, the development server is available on
`http://localhost:4200/` and is configured to access the API at
`http://localhost:8000/api/`, which is the default of the backend. If
you enabled DEBUG on the back end, several security overrides for
allowed hosts, CORS and X-Frame-Options are in place so that the front
end behaves exactly as in production. This also relies on you being
logged into the back end. Without a valid session, The front end will
simply not work.
```bash
$ npm install
```
Testing and code style:
4. You can launch a development server by running:
- The frontend code (.ts, .html, .scss) use `prettier` for code
```bash
$ ng serve
```
This will automatically update whenever you save. However, in-place
compilation might fail on syntax errors, in which case you need to
restart it.
By default, the development server is available on `http://localhost:4200/` and is configured to access the API at
`http://localhost:8000/api/`, which is the default of the backend. If you enabled `DEBUG` on the back end, several security overrides for allowed hosts, CORS and X-Frame-Options are in place so that the front end behaves exactly as in production.
### Testing and code style
- The front end code (.ts, .html, .scss) use `prettier` for code
formatting via the Git `pre-commit` hooks which run automatically on
commit. See
[above](#code-formatting-with-pre-commit-hooks) for installation. You can also run this via cli with a
commit. See [above](#code-formatting-with-pre-commit-hooks) for installation instructions. You can also run this via the CLI with a
command such as
```shell-session
```bash
$ git ls-files -- '*.ts' | xargs pre-commit run prettier --files
```
- Frontend testing uses jest and cypress. There is currently a need
for significantly more frontend tests. Unit tests and e2e tests,
- Front end testing uses jest and cypress. There is currently a need
for significantly more front end tests. Unit tests and e2e tests,
respectively, can be run non-interactively with:
```shell-session
```bash
$ ng test
$ npm run e2e:ci
```
Cypress also includes a UI which can be run from within the `src-ui`
directory with
- Cypress also includes a UI which can be run with:
```shell-session
$ ./node_modules/.bin/cypress open
```bash
$ ./node_modules/.bin/cypress open
```
- In order to build the front end and serve it as part of Django, execute:
```bash
$ ng build --configuration production
```
In order to build the front end and serve it as part of django, execute
```shell-session
$ ng build --configuration production
```
This will build the front end and put it in a location from which the
Django server will serve it as static content. This way, you can verify
that authentication is working.
This will build the front end and put it in a location from which the
Django server will serve it as static content. This way, you can verify
that authentication is working.
## Localization
Paperless is available in many different languages. Since paperless
consists both of a django application and an Angular front end, both
Paperless-ngx is available in many different languages. Since Paperless-ngx
consists both of a Django application and an AngularJS front end, both
these parts have to be translated separately.
### Front end localization
- The Angular front end does localization according to the [Angular
- The AngularJS front end does localization according to the [Angular
documentation](https://angular.io/guide/i18n).
- The source language of the project is "en_US".
- The source strings end up in the file "src-ui/messages.xlf".
- The source strings end up in the file `src-ui/messages.xlf`.
- The translated strings need to be placed in the
"src-ui/src/locale/" folder.
`src-ui/src/locale/` folder.
- In order to extract added or changed strings from the source files,
call `ng xi18n --ivy`.
call `ng extract-i18n`.
Adding new languages requires adding the translated files in the
"src-ui/src/locale/" folder and adjusting a couple files.
`src-ui/src/locale/` folder and adjusting a couple files.
1. Adjust "src-ui/angular.json":
1. Adjust `src-ui/angular.json`:
```json
"i18n": {
@@ -292,7 +278,7 @@ Adding new languages requires adding the translated files in the
```
2. Add the language to the available options in
"src-ui/src/app/services/settings.service.ts":
`src-ui/src/app/services/settings.service.ts`:
```typescript
getLanguageOptions(): LanguageOption[] {
@@ -313,7 +299,7 @@ Adding new languages requires adding the translated files in the
and "yyyy".
3. Import and register the Angular data for this locale in
"src-ui/src/app/app.module.ts":
`src-ui/src/app/app.module.ts`:
```typescript
import localeDe from '@angular/common/locales/de'
@@ -326,10 +312,10 @@ A majority of the strings that appear in the back end appear only when
the admin is used. However, some of these are still shown on the front
end (such as error messages).
- The django application does localization according to the [django
- The django application does localization according to the [Django
documentation](https://docs.djangoproject.com/en/3.1/topics/i18n/translation/).
- The source language of the project is "en_US".
- Localization files end up in the folder "src/locale/".
- Localization files end up in the folder `src/locale/`.
- In order to extract strings from the application, call
`python3 manage.py makemessages -l en_US`. This is important after
making changes to translatable strings.
@@ -340,8 +326,8 @@ end (such as error messages).
command.
Adding new languages requires adding the translated files in the
"src/locale/" folder and adjusting the file
"src/paperless/settings.py" to include the new language:
`src/locale/`-folder and adjusting the file
`src/paperless/settings.py` to include the new language:
```python
LANGUAGES = [
@@ -360,18 +346,27 @@ LANGUAGES = [
The documentation is built using material-mkdocs, see their [documentation](https://squidfunk.github.io/mkdocs-material/reference/).
If you want to build the documentation locally, this is how you do it:
1. Install python dependencies.
1. Have an active pipenv shell (`pipenv shell`) and install Python dependencies:
```shell-session
$ cd /path/to/paperless
```bash
$ pipenv install --dev
```
2. Build the documentation
```shell-session
$ cd /path/to/paperless
$ pipenv mkdocs build --config-file mkdocs.yml
```bash
$ mkdocs build --config-file mkdocs.yml
```
_alternatively..._
3. Serve the documentation. This will spin up a
copy of the documentation at http://127.0.0.1:8000
that will automatically refresh everytime you change
something.
```bash
$ mkdocs serve
```
## Building the Docker image
@@ -384,35 +379,35 @@ helper script `build-docker-image.sh`.
Building the docker image from source:
```shell-session
```bash
./build-docker-image.sh Dockerfile -t <your-tag>
```
## Extending Paperless
## Extending Paperless-ngx
Paperless does not have any fancy plugin systems and will probably never
Paperless-ngx does not have any fancy plugin systems and will probably never
have. However, some parts of the application have been designed to allow
easy integration of additional features without any modification to the
base code.
### Making custom parsers
Paperless uses parsers to add documents to paperless. A parser is
Paperless-ngx uses parsers to add documents. A parser is
responsible for:
- Retrieve the content from the original
- Create a thumbnail
- Optional: Retrieve a created date from the original
- Optional: Create an archived document from the original
- Retrieving the content from the original
- Creating a thumbnail
- _optional:_ Retrieving a created date from the original
- _optional:_ Creainge an archived document from the original
Custom parsers can be added to paperless to support more file types. In
Custom parsers can be added to Paperless-ngx to support more file types. In
order to do that, you need to write the parser itself and announce its
existence to paperless.
existence to Paperless-ngx.
The parser itself must extend `documents.parsers.DocumentParser` and
must implement the methods `parse` and `get_thumbnail`. You can provide
your own implementation to `get_date` if you don't want to rely on
paperless' default date guessing mechanisms.
Paperless-ngx' default date guessing mechanisms.
```python
class MyCustomParser(DocumentParser):
@@ -444,7 +439,7 @@ to be empty and removed after consumption finished. You can use that
directory to store any intermediate files and also use it to store the
thumbnail / archived document.
After that, you need to announce your parser to paperless. You need to
After that, you need to announce your parser to Paperless-ngx. You need to
connect a handler to the `document_consumer_declaration` signal. Have a
look in the file `src/paperless_tesseract/apps.py` on how that's done.
The handler is a method that returns information about your parser:
@@ -464,11 +459,11 @@ def myparser_consumer_declaration(sender, **kwargs):
- `parser` is a reference to a class that extends `DocumentParser`.
- `weight` is used whenever two or more parsers are able to parse a
file: The parser with the higher weight wins. This can be used to
override the parsers provided by paperless.
override the parsers provided by Paperless-ngx.
- `mime_types` is a dictionary. The keys are the mime types your
parser supports and the value is the default file extension that
paperless should use when storing files and serving them for
Paperless-ngx should use when storing files and serving them for
download. We could guess that from the file extensions, but some
mime types have many extensions associated with them and the python
mime types have many extensions associated with them and the Python
methods responsible for guessing the extension do not always return
the same value.

View File

@@ -43,7 +43,7 @@ steps described in [Docker setup](#docker_hub) automatically.
```
2. Go to the [/docker/compose directory on the project
page](https://github.com/paperless-ngx/paperless-ngx/tree/master/docker/compose)
page](https://github.com/paperless-ngx/paperless-ngx/tree/main/docker/compose)
and download one of the `docker-compose.*.yml` files,
depending on which database backend you want to use. Rename this
file to `docker-compose.yml`. If you want to enable
@@ -160,8 +160,7 @@ steps described in [Docker setup](#docker_hub) automatically.
`PAPERLESS_CONSUMER_POLLING`, which will disable inotify. See
[here](/configuration#polling).
6. Run `docker-compose pull`, followed by `docker-compose up -d`. This
will pull the image, create and start the necessary containers.
6. Run `docker-compose pull`. This will pull the image.
7. To be able to login, you will need a super user. To create it,
execute the following command:
@@ -173,7 +172,9 @@ steps described in [Docker setup](#docker_hub) automatically.
This will prompt you to set a username, an optional e-mail address
and finally a password (at least 8 characters).
8. The default `docker-compose.yml` exports the webserver on your local
8. Run `docker-compose up -d`. This will create and start the necessary containers.
9. The default `docker-compose.yml` exports the webserver on your local
port
8000\. If you did not change this, you should now be able to visit
@@ -189,7 +190,7 @@ steps described in [Docker setup](#docker_hub) automatically.
git clone https://github.com/paperless-ngx/paperless-ngx
```
The master branch always reflects the latest stable version.
The main branch always reflects the latest stable version.
2. Copy one of the `docker/compose/docker-compose.*.yml` to
`docker-compose.yml` in the root folder, depending on which database
@@ -365,6 +366,10 @@ supported.
documents are written in.
- Set `PAPERLESS_TIME_ZONE` to your local time zone.
!!! warning
Ensure your Redis instance [is secured](https://redis.io/docs/getting-started/#securing-redis).
7. Create the following directories if they are missing:
- `/opt/paperless/media`
@@ -388,12 +393,7 @@ supported.
```
8. Install python requirements from the `requirements.txt` file. 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.
```shell-session
sudo -Hu paperless pip3 install --upgrade pip
```
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.
```shell-session
sudo -Hu paperless pip3 install -r requirements.txt
@@ -590,7 +590,7 @@ Migration to paperless-ngx is then performed in a few simple steps:
3. Download the latest release of paperless-ngx. You can either go with
the docker-compose files from
[here](https://github.com/paperless-ngx/paperless-ngx/tree/master/docker/compose)
[here](https://github.com/paperless-ngx/paperless-ngx/tree/main/docker/compose)
or clone the repository to build the image yourself (see
[above](#docker_build)). You can
either replace your current paperless folder or put paperless-ngx in
@@ -713,6 +713,12 @@ below use PostgreSQL, but are applicable to MySQL/MariaDB with the
MySQL also enforces limits on maximum lengths, but does so differently than
PostgreSQL. It may not be possible to migrate to MySQL due to this.
!!! warning
Using mariadb version 10.4+ is recommended. Using the `utf8mb3` character set on
an older system may fix issues that can arise while setting up Paperless-ngx but
`utf8mb3` can cause issues with consumption (where `utf8mb4` does not).
1. Stop paperless, if it is running.
2. Tell paperless to use PostgreSQL:
@@ -817,14 +823,14 @@ performance immensely:
other tasks).
- Keep `PAPERLESS_OCR_MODE` at its default value `skip` and consider
OCR'ing your documents before feeding them into paperless. Some
scanners are able to do this! You might want to even specify
`skip_noarchive` to skip archive file generation for already ocr'ed
documents entirely.
scanners are able to do this!
- Set `PAPERLESS_OCR_SKIP_ARCHIVE_FILE` to `with_text` to skip archive
file generation for already ocr'ed documents, or `always` to skip it
for all documents.
- If you want to perform OCR on the device, consider using
`PAPERLESS_OCR_CLEAN=none`. This will speed up OCR times and use
less memory at the expense of slightly worse OCR results.
- If using docker, consider setting `PAPERLESS_WEBSERVER_WORKERS` to
1. This will save some memory.
- If using docker, consider setting `PAPERLESS_WEBSERVER_WORKERS` to 1. This will save some memory.
- Consider setting `PAPERLESS_ENABLE_NLTK` to false, to disable the
more advanced language processing, which can take more memory and
processing time.

View File

@@ -332,3 +332,16 @@ change the port gunicorn listens on.
To fix this, set `PAPERLESS_PORT` again to your desired port, or the
default of 8000.
## Database Warns about unique constraint "documents_tag_name_uniq
You may see database log lines like:
```
ERROR: duplicate key value violates unique constraint "documents_tag_name_uniq"
DETAIL: Key (name)=(NameF) already exists.
STATEMENT: INSERT INTO "documents_tag" ("owner_id", "name", "match", "matching_algorithm", "is_insensitive", "color", "is_inbox_tag") VALUES (NULL, 'NameF', '', 1, true, '#a6cee3', false) RETURNING "documents_tag"."id"
```
This can happen during heavy consumption when using polling. Paperless will handle it correctly and the file
will still be consumed

View File

@@ -60,8 +60,8 @@ following operations on 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
configure that by configuring
`PAPERLESS_OCR_SKIP_ARCHIVE_FILE=with_text`. Please read the
[relevant section in the documentation](/configuration#ocr).
!!! note
@@ -202,6 +202,39 @@ configured via `PAPERLESS_EMAIL_TASK_CRON` (see [software tweaks](/configuration
You can also submit a document using the REST API, see [POSTing documents](/api#file-uploads)
for details.
## Permissions
As of version 1.13.0 Paperless-ngx added core support for user / group permissions. Permissions is
based around an object 'owner' and 'view' and 'edit' permissions can be granted to other users
or groups.
Permissions uses the built-in user model of the backend framework, Django.
!!! note
After migration to version 1.13.0 all existing documents, tags etc. will have no explicit owner
set which means they will be visible / editable by all users. Once an object has an owner set,
only the owner can explicitly grant / revoke permissions.
!!! note
When first migrating to permissions it is recommended to user a 'superuser' account (which
would usually have been setup during installation) to ensure you have full permissions.
Note that superusers have access to all objects.
Permissions can be set using the new "Permissions" tab when editing documents, or bulk-applied
in the UI by selecting documents and choosing the "Permissions" button. Owner can also optionally
be set for documents uploaded via the API. Documents consumed via the consumption dir currently
do not have an owner set.
### Users and Groups
Paperless-ngx versions after 1.13.0 allow creating and editing users and groups via the 'frontend' UI.
These can be found under Settings > Users & Groups, assuming the user has access. If a user is designated
as a member of a group those permissions will be inherited and this is reflected in the UI. Explicit
permissions can be granted to limit access to certain parts of the UI (and corresponding API endpoints).
## Best practices {#basic-searching}
Paperless offers a couple tools that help you organize your document

View File

@@ -30,7 +30,9 @@ def worker_int(worker):
worker.log.info("worker received INT or QUIT signal")
## get traceback info
import threading, sys, traceback
import sys
import threading
import traceback
id2name = {th.ident: th.name for th in threading.enumerate()}
code = []

View File

@@ -321,7 +321,7 @@ fi
wget "https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.$DOCKER_COMPOSE_VERSION.yml" -O docker-compose.yml
wget "https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/.env" -O .env
SECRET_KEY=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 64 | head -n 1)
SECRET_KEY=$(tr --delete --complement 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head --bytes 64)
DEFAULT_LANGUAGES=("deu eng fra ita spa")
@@ -346,7 +346,7 @@ read -r -a OCR_LANGUAGES_ARRAY <<< "${_split_langs}"
fi
} > docker-compose.env
sed -i "s/- 8000:8000/- $PORT:8000/g" docker-compose.yml
sed -i "s/- \"8000:8000\"/- \"$PORT:8000\"/g" docker-compose.yml
sed -i "s#- \./consume:/usr/src/paperless/consume#- $CONSUME_FOLDER:/usr/src/paperless/consume#g" docker-compose.yml

View File

@@ -41,6 +41,7 @@ markdown_extensions:
anchor_linenums: true
- pymdownx.superfences
- pymdownx.inlinehilite
- pymdownx.snippets
strict: true
nav:
- index.md
@@ -54,7 +55,7 @@ nav:
- 'FAQs': faq.md
- troubleshooting.md
- changelog.md
copyright: Copyright &copy; 2016 - 2022 Daniel Quinn, Jonas Winkler, and the Paperless-ngx team
copyright: Copyright &copy; 2016 - 2023 Daniel Quinn, Jonas Winkler, and the Paperless-ngx team
extra:
social:
- icon: fontawesome/brands/github

View File

@@ -42,6 +42,7 @@
#PAPERLESS_OCR_LANGUAGE=eng
#PAPERLESS_OCR_MODE=skip
#PAPERLESS_OCR_SKIP_ARCHIVE_FILE=never
#PAPERLESS_OCR_OUTPUT_TYPE=pdfa
#PAPERLESS_OCR_PAGES=1
#PAPERLESS_OCR_IMAGE_DPI=300

View File

@@ -2,5 +2,5 @@
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 gotenberg/gotenberg:7.6 gotenberg --chromium-disable-javascript=true --chromium-allow-list="file:///tmp/.*"
docker run -p 3000:3000 -d gotenberg/gotenberg:7.8 gotenberg --chromium-disable-javascript=true --chromium-allow-list="file:///tmp/.*"
docker run -p 9998:9998 -d ghcr.io/paperless-ngx/tika:latest

View File

@@ -192,7 +192,8 @@
"cli": {
"schematicCollections": [
"@angular-eslint/schematics"
]
],
"analytics": false
},
"schematics": {
"@angular-eslint/schematics:application": {

View File

@@ -2,6 +2,7 @@ import { defineConfig } from 'cypress'
export default defineConfig({
videosFolder: 'cypress/videos',
video: false,
screenshotsFolder: 'cypress/screenshots',
fixturesFolder: 'cypress/fixtures',
e2e: {

View File

@@ -0,0 +1,68 @@
describe('settings', () => {
beforeEach(() => {
// also uses global fixtures from cypress/support/e2e.ts
// mock restricted permissions
cy.intercept('http://localhost:8000/api/ui_settings/', {
fixture: 'ui_settings/settings_restricted.json',
})
})
it('should not allow user to edit settings', () => {
cy.visit('/dashboard')
cy.contains('Settings').should('not.exist')
cy.visit('/settings').wait(2000)
cy.contains("You don't have permissions to do that").should('exist')
})
it('should not allow user to view documents', () => {
cy.visit('/dashboard')
cy.contains('Documents').should('not.exist')
cy.visit('/documents').wait(2000)
cy.contains("You don't have permissions to do that").should('exist')
cy.visit('/documents/1').wait(2000)
cy.contains("You don't have permissions to do that").should('exist')
})
it('should not allow user to view correspondents', () => {
cy.visit('/dashboard')
cy.contains('Correspondents').should('not.exist')
cy.visit('/correspondents').wait(2000)
cy.contains("You don't have permissions to do that").should('exist')
})
it('should not allow user to view tags', () => {
cy.visit('/dashboard')
cy.contains('Tags').should('not.exist')
cy.visit('/tags').wait(2000)
cy.contains("You don't have permissions to do that").should('exist')
})
it('should not allow user to view document types', () => {
cy.visit('/dashboard')
cy.contains('Document Types').should('not.exist')
cy.visit('/documenttypes').wait(2000)
cy.contains("You don't have permissions to do that").should('exist')
})
it('should not allow user to view storage paths', () => {
cy.visit('/dashboard')
cy.contains('Storage Paths').should('not.exist')
cy.visit('/storagepaths').wait(2000)
cy.contains("You don't have permissions to do that").should('exist')
})
it('should not allow user to view logs', () => {
cy.visit('/dashboard')
cy.contains('Logs').should('not.exist')
cy.visit('/logs').wait(2000)
cy.contains("You don't have permissions to do that").should('exist')
})
it('should not allow user to view tasks', () => {
cy.visit('/dashboard')
cy.contains('Tasks').should('not.exist')
cy.visit('/tasks').wait(2000)
cy.contains("You don't have permissions to do that").should('exist')
})
})

View File

@@ -17,28 +17,28 @@ describe('document-detail', () => {
req.reply({ result: 'OK' })
}).as('saveDoc')
cy.fixture('documents/1/comments.json').then((commentsJson) => {
cy.fixture('documents/1/notes.json').then((notesJson) => {
cy.intercept(
'GET',
'http://localhost:8000/api/documents/1/comments/',
'http://localhost:8000/api/documents/1/notes/',
(req) => {
req.reply(commentsJson.filter((c) => c.id != 10)) // 3
req.reply(notesJson.filter((c) => c.id != 10)) // 3
}
)
cy.intercept(
'DELETE',
'http://localhost:8000/api/documents/1/comments/?id=9',
'http://localhost:8000/api/documents/1/notes/?id=9',
(req) => {
req.reply(commentsJson.filter((c) => c.id != 9 && c.id != 10)) // 2
req.reply(notesJson.filter((c) => c.id != 9 && c.id != 10)) // 2
}
)
cy.intercept(
'POST',
'http://localhost:8000/api/documents/1/comments/',
'http://localhost:8000/api/documents/1/notes/',
(req) => {
req.reply(commentsJson) // 4
req.reply(notesJson) // 4
}
)
})
@@ -75,33 +75,40 @@ describe('document-detail', () => {
cy.get('pdf-viewer').should('be.visible')
})
it('should show a list of comments', () => {
cy.wait(1000)
.get('a')
.contains('Comments')
.click({ force: true })
.wait(1000)
cy.get('app-document-comments').find('.card').its('length').should('eq', 3)
it('should show a list of notes', () => {
cy.wait(1000).get('a').contains('Notes').click({ force: true }).wait(1000)
cy.get('app-document-notes').find('.card').its('length').should('eq', 3)
})
it('should support comment deletion', () => {
cy.wait(1000).get('a').contains('Comments').click().wait(1000)
cy.get('app-document-comments')
it('should support note deletion', () => {
cy.wait(1000).get('a').contains('Notes').click().wait(1000)
cy.get('app-document-notes')
.find('.card')
.first()
.find('button')
.click({ force: true })
.wait(500)
cy.get('app-document-comments').find('.card').its('length').should('eq', 2)
cy.get('app-document-notes').find('.card').its('length').should('eq', 2)
})
it('should support comment insertion', () => {
cy.wait(1000).get('a').contains('Comments').click().wait(1000)
cy.get('app-document-comments')
it('should support note insertion', () => {
cy.wait(1000).get('a').contains('Notes').click().wait(1000)
cy.get('app-document-notes')
.find('form textarea')
.type('Testing new comment')
.type('Testing new note')
.wait(500)
cy.get('app-document-comments').find('form button').click().wait(1500)
cy.get('app-document-comments').find('.card').its('length').should('eq', 4)
cy.get('app-document-notes').find('form button').click().wait(1500)
cy.get('app-document-notes').find('.card').its('length').should('eq', 4)
})
it('should support navigation to notes tab by url', () => {
cy.visit('/documents/1/notes')
cy.get('app-document-notes').should('exist')
})
it('should dynamically update note counts', () => {
cy.visit('/documents/1/notes')
cy.get('app-document-notes').within(() => cy.contains('Delete').click())
cy.get('ul.nav').find('li').contains('Notes').find('.badge').contains('2')
})
})

View File

@@ -48,6 +48,26 @@ describe('documents-list', () => {
(d.tags as Array<number>).includes(tag_id)
)
response.count = response.results.length
} else if (req.query.hasOwnProperty('correspondent__id__in')) {
// filtering e.g. http://localhost:8000/api/documents/?page=1&page_size=50&ordering=-created&correspondent__id__in=9,14
const correspondent_ids = req.query['correspondent__id__in']
.toString()
.split(',')
.map((c) => +c)
response.results = (documentsJson.results as Array<any>).filter((d) =>
correspondent_ids.includes(d.correspondent)
)
response.count = response.results.length
} else if (req.query.hasOwnProperty('correspondent__id__none')) {
// filtering e.g. http://localhost:8000/api/documents/?page=1&page_size=50&ordering=-created&correspondent__id__none=9,14
const correspondent_ids = req.query['correspondent__id__none']
.toString()
.split(',')
.map((c) => +c)
response.results = (documentsJson.results as Array<any>).filter(
(d) => !correspondent_ids.includes(d.correspondent)
)
response.count = response.results.length
}
req.reply(response)
@@ -112,6 +132,27 @@ describe('documents-list', () => {
cy.contains('One document')
})
it('should filter including multiple correspondents', () => {
cy.get('app-filter-editor app-filterable-dropdown[title="Correspondent"]')
.click()
.within(() => {
cy.contains('button', 'ABC Test Correspondent').click()
cy.contains('button', 'Corresp 11').click()
})
cy.contains('3 documents')
})
it('should filter excluding multiple correspondents', () => {
cy.get('app-filter-editor app-filterable-dropdown[title="Correspondent"]')
.click()
.within(() => {
cy.contains('button', 'ABC Test Correspondent').click()
cy.contains('button', 'Corresp 11').click()
cy.contains('label', 'Exclude').click()
})
cy.contains('One document')
})
it('should apply tags', () => {
cy.get('app-document-card-small:first-of-type').click()
cy.get('app-bulk-editor app-filterable-dropdown[title="Tags"]').within(

View File

@@ -232,6 +232,11 @@ describe('documents query params', () => {
it('should show a list of documents filtered by document type', () => {
cy.visit('/documents?sort=created&reverse=true&document_type__id=1')
cy.contains('2 documents')
})
it('should show a list of documents filtered by multiple correspondents', () => {
cy.visit('/documents?sort=created&reverse=true&document_type__id__in=1,2')
cy.contains('3 documents')
})
@@ -245,9 +250,14 @@ describe('documents query params', () => {
cy.contains('2 documents')
})
it('should show a list of documents filtered by multiple correspondents', () => {
cy.visit('/documents?sort=created&reverse=true&correspondent__id__in=9,14')
cy.contains('3 documents')
})
it('should show a list of documents filtered by no correspondent', () => {
cy.visit('/documents?sort=created&reverse=true&correspondent__isnull=1')
cy.contains('2 documents')
cy.contains('One document')
})
it('should show a list of documents filtered by storage path', () => {

View File

@@ -115,7 +115,7 @@ describe('settings', () => {
cy.contains('a', 'Dashboard').click()
cy.contains('You have unsaved changes')
cy.contains('button', 'Cancel').click()
cy.contains('button', 'Save').click().wait('@savedViews').wait(2000)
cy.contains('button', 'Save').click().wait(2000)
cy.contains('a', 'Dashboard').click()
cy.contains('You have unsaved changes').should('not.exist')
})

View File

@@ -1 +1,257 @@
{"count":27,"next":"http://localhost:8000/api/correspondents/?page=2","previous":null,"results":[{"id":9,"slug":"abc-test-correspondent","name":"ABC Test Correspondent","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":13,"slug":"corresp-10","name":"Corresp 10","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":14,"slug":"corresp-11","name":"Corresp 11","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":15,"slug":"corresp-12","name":"Corresp 12","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":16,"slug":"corresp-13","name":"Corresp 13","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":18,"slug":"corresp-15","name":"Corresp 15","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":19,"slug":"corresp-16","name":"Corresp 16","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":20,"slug":"corresp-17","name":"Corresp 17","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":21,"slug":"corresp-18","name":"Corresp 18","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":22,"slug":"corresp-19","name":"Corresp 19","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":23,"slug":"corresp-20","name":"Corresp 20","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":24,"slug":"corresp-21","name":"Corresp 21","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":25,"slug":"corresp-22","name":"Corresp 22","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":26,"slug":"corresp-23","name":"Corresp 23","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":5,"slug":"corresp-3","name":"Corresp 3","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":6,"slug":"corresp-4","name":"Corresp 4","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":7,"slug":"corresp-5","name":"Corresp 5","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":8,"slug":"corresp-6","name":"Corresp 6","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":10,"slug":"corresp-7","name":"Corresp 7","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":11,"slug":"corresp-8","name":"Corresp 8","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":12,"slug":"corresp-9","name":"Corresp 9","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":17,"slug":"correspondent-14","name":"Correspondent 14","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0,"last_correspondence":null},{"id":2,"slug":"correspondent-2","name":"Correspondent 2","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":7,"last_correspondence":"2021-01-20T23:37:58.204614Z"},{"id":27,"slug":"michael-shamoon","name":"Michael Shamoon","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":1,"last_correspondence":"2022-03-16T03:48:50.089624Z"},{"id":4,"slug":"newest-correspondent","name":"Newest Correspondent","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":1,"last_correspondence":"2021-02-07T08:00:00Z"}]}
{
"count": 27,
"next": "http://localhost:8000/api/correspondents/?page=2",
"previous": null,
"results": [
{
"id": 9,
"slug": "abc-test-correspondent",
"name": "ABC Test Correspondent",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 13,
"slug": "corresp-10",
"name": "Corresp 10",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 14,
"slug": "corresp-11",
"name": "Corresp 11",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 15,
"slug": "corresp-12",
"name": "Corresp 12",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 16,
"slug": "corresp-13",
"name": "Corresp 13",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 18,
"slug": "corresp-15",
"name": "Corresp 15",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 19,
"slug": "corresp-16",
"name": "Corresp 16",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 20,
"slug": "corresp-17",
"name": "Corresp 17",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 21,
"slug": "corresp-18",
"name": "Corresp 18",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 22,
"slug": "corresp-19",
"name": "Corresp 19",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 23,
"slug": "corresp-20",
"name": "Corresp 20",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 24,
"slug": "corresp-21",
"name": "Corresp 21",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 25,
"slug": "corresp-22",
"name": "Corresp 22",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 26,
"slug": "corresp-23",
"name": "Corresp 23",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 5,
"slug": "corresp-3",
"name": "Corresp 3",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 6,
"slug": "corresp-4",
"name": "Corresp 4",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 7,
"slug": "corresp-5",
"name": "Corresp 5",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 8,
"slug": "corresp-6",
"name": "Corresp 6",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 10,
"slug": "corresp-7",
"name": "Corresp 7",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 11,
"slug": "corresp-8",
"name": "Corresp 8",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 12,
"slug": "corresp-9",
"name": "Corresp 9",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 17,
"slug": "correspondent-14",
"name": "Correspondent 14",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 0,
"last_correspondence": null
},
{
"id": 2,
"slug": "correspondent-2",
"name": "Correspondent 2",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 7,
"last_correspondence": "2021-01-20T23:37:58.204614Z"
},
{
"id": 27,
"slug": "correspondent-slug",
"name": "Correspondent Slug",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 1,
"last_correspondence": "2022-03-16T03:48:50.089624Z"
},
{
"id": 4,
"slug": "newest-correspondent",
"name": "Newest Correspondent",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 1,
"last_correspondence": "2021-02-07T08:00:00Z"
}
]
}

View File

@@ -1 +1,25 @@
{"count":1,"next":null,"previous":null,"results":[{"id":1,"slug":"test","name":"Test Doc Type","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0}]}
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"slug": "test",
"name": "Test Doc Type",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 1
},
{
"id": 2,
"slug": "test2",
"name": "Test Doc Type 2",
"match": "",
"matching_algorithm": 1,
"is_insensitive": true,
"document_count": 1
}
]
}

View File

@@ -1,46 +0,0 @@
[
{
"id": 10,
"comment": "Testing new comment",
"created": "2022-08-08T04:24:55.176008Z",
"user": {
"id": 1,
"username": "user2",
"firstname": "",
"lastname": ""
}
},
{
"id": 9,
"comment": "Testing one more time",
"created": "2022-02-18T04:24:55.176008Z",
"user": {
"id": 2,
"username": "user1",
"firstname": "",
"lastname": ""
}
},
{
"id": 8,
"comment": "Another comment",
"created": "2021-11-08T04:24:47.925042Z",
"user": {
"id": 2,
"username": "user33",
"firstname": "",
"lastname": ""
}
},
{
"id": 7,
"comment": "Cupcake ipsum dolor sit amet cheesecake candy cookie tiramisu. Donut chocolate chupa chups macaroon brownie halvah pie cheesecake gummies. Sweet chocolate bar candy donut gummi bears bear claw liquorice bonbon shortbread.\n\nDonut chocolate bar candy wafer wafer tiramisu. Gummies chocolate cake muffin toffee carrot cake macaroon. Toffee toffee jelly beans danish lollipop cake.",
"created": "2021-02-08T02:37:49.724132Z",
"user": {
"id": 3,
"username": "admin",
"firstname": "",
"lastname": ""
}
}
]

View File

@@ -0,0 +1,26 @@
[
{
"id": 10,
"note": "Testing new note",
"created": "2022-08-08T04:24:55.176008Z",
"user": 3
},
{
"id": 9,
"note": "Testing one more time",
"created": "2022-02-18T04:24:55.176008Z",
"user": 15
},
{
"id": 8,
"note": "Another note",
"created": "2021-11-08T04:24:47.925042Z",
"user": 3
},
{
"id": 7,
"note": "Cupcake ipsum dolor sit amet cheesecake candy cookie tiramisu. Donut chocolate chupa chups macaroon brownie halvah pie cheesecake gummies. Sweet chocolate bar candy donut gummi bears bear claw liquorice bonbon shortbread.\n\nDonut chocolate bar candy wafer wafer tiramisu. Gummies chocolate cake muffin toffee carrot cake macaroon. Toffee toffee jelly beans danish lollipop cake.",
"created": "2021-02-08T02:37:49.724132Z",
"user": 3
}
]

View File

@@ -14,11 +14,43 @@
4
],
"created": "2022-03-22T07:24:18Z",
"created_date": "2022-03-22",
"modified": "2022-03-22T07:24:23.264859Z",
"added": "2022-03-22T07:24:22.922631Z",
"archive_serial_number": null,
"original_file_name": "2022-03-22 no latin title.pdf",
"archived_file_name": "2022-03-22 no latin title.pdf"
"archived_file_name": "2022-03-22 no latin title.pdf",
"owner": null,
"permissions": {
"view": {
"users": [],
"groups": []
},
"change": {
"users": [],
"groups": []
}
},
"notes": [
{
"id": 9,
"note": "Testing one more time",
"created": "2022-02-18T04:24:55.176008Z",
"user": 15
},
{
"id": 8,
"note": "Another note",
"created": "2021-11-08T04:24:47.925042Z",
"user": 3
},
{
"id": 7,
"note": "Cupcake ipsum dolor sit amet cheesecake candy cookie tiramisu. Donut chocolate chupa chups macaroon brownie halvah pie cheesecake gummies. Sweet chocolate bar candy donut gummi bears bear claw liquorice bonbon shortbread.\n\nDonut chocolate bar candy wafer wafer tiramisu. Gummies chocolate cake muffin toffee carrot cake macaroon. Toffee toffee jelly beans danish lollipop cake.",
"created": "2021-02-08T02:37:49.724132Z",
"user": 3
}
]
},
{
"id": 2,
@@ -29,15 +61,28 @@
"content": "Test document PDF",
"tags": [],
"created": "2022-03-23T07:24:18Z",
"created_date": "2022-03-23",
"modified": "2022-03-23T07:24:23.264859Z",
"added": "2022-03-23T07:24:22.922631Z",
"archive_serial_number": 12345,
"original_file_name": "2022-03-23 lorem ipsum dolor sit amet.pdf",
"archived_file_name": "2022-03-23 llorem ipsum dolor sit amet.pdf"
"archived_file_name": "2022-03-23 llorem ipsum dolor sit amet.pdf",
"owner": null,
"permissions": {
"view": {
"users": [],
"groups": []
},
"change": {
"users": [],
"groups": []
}
},
"notes": []
},
{
"id": 3,
"correspondent": null,
"correspondent": 14,
"document_type": 1,
"storage_path": null,
"title": "dolor",
@@ -46,16 +91,29 @@
2
],
"created": "2022-03-24T07:24:18Z",
"created_date": "2022-03-24",
"modified": "2022-03-24T07:24:23.264859Z",
"added": "2022-03-24T07:24:22.922631Z",
"archive_serial_number": null,
"original_file_name": "2022-03-24 dolor.pdf",
"archived_file_name": "2022-03-24 dolor.pdf"
"archived_file_name": "2022-03-24 dolor.pdf",
"owner": null,
"permissions": {
"view": {
"users": [],
"groups": []
},
"change": {
"users": [],
"groups": []
}
},
"notes": []
},
{
"id": 4,
"correspondent": 9,
"document_type": 1,
"document_type": 2,
"storage_path": null,
"title": "sit amet",
"content": "Test document PDF",
@@ -63,11 +121,24 @@
4, 5
],
"created": "2022-06-01T07:24:18Z",
"created_date": "2022-06-01",
"modified": "2022-06-01T07:24:23.264859Z",
"added": "2022-06-01T07:24:22.922631Z",
"archive_serial_number": 12347,
"original_file_name": "2022-06-01 sit amet.pdf",
"archived_file_name": "2022-06-01 sit amet.pdf"
"archived_file_name": "2022-06-01 sit amet.pdf",
"owner": null,
"permissions": {
"view": {
"users": [],
"groups": []
},
"change": {
"users": [],
"groups": []
}
},
"notes": []
}
]
}

View File

@@ -0,0 +1,119 @@
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 6,
"name": "Another Group",
"permissions": [
"add_user",
"change_user",
"delete_user",
"view_user",
"add_note",
"change_note",
"delete_note",
"view_note"
]
},
{
"id": 1,
"name": "First Group",
"permissions": [
"add_group",
"change_group",
"delete_group",
"view_group",
"add_permission",
"change_permission",
"delete_permission",
"view_permission",
"add_token",
"change_token",
"delete_token",
"view_token",
"add_tokenproxy",
"change_tokenproxy",
"delete_tokenproxy",
"view_tokenproxy",
"add_contenttype",
"change_contenttype",
"delete_contenttype",
"view_contenttype",
"add_chordcounter",
"change_chordcounter",
"delete_chordcounter",
"view_chordcounter",
"add_groupresult",
"change_groupresult",
"delete_groupresult",
"view_groupresult",
"add_taskresult",
"change_taskresult",
"delete_taskresult",
"view_taskresult",
"add_failure",
"change_failure",
"delete_failure",
"view_failure",
"add_ormq",
"change_ormq",
"delete_ormq",
"view_ormq",
"add_schedule",
"change_schedule",
"delete_schedule",
"view_schedule",
"add_success",
"change_success",
"delete_success",
"view_success",
"add_task",
"change_task",
"delete_task",
"view_task",
"add_note",
"change_note",
"delete_note",
"view_note",
"add_correspondent",
"change_correspondent",
"delete_correspondent",
"view_correspondent",
"add_document",
"change_document",
"delete_document",
"view_document",
"add_documenttype",
"change_documenttype",
"delete_documenttype",
"view_documenttype",
"add_frontendsettings",
"change_frontendsettings",
"delete_frontendsettings",
"view_frontendsettings",
"add_log",
"change_log",
"delete_log",
"view_log",
"add_savedview",
"change_savedview",
"delete_savedview",
"view_savedview",
"add_savedviewfilterrule",
"change_savedviewfilterrule",
"delete_savedviewfilterrule",
"view_savedviewfilterrule",
"add_taskattributes",
"change_taskattributes",
"delete_taskattributes",
"view_taskattributes",
"add_session",
"change_session",
"delete_session",
"view_session"
]
}
]
}

View File

@@ -9,6 +9,7 @@
"account": 2,
"folder": "INBOX",
"filter_from": null,
"filter_to": null,
"filter_subject": "[paperless]",
"filter_body": null,
"filter_attachment_filename": null,

View File

@@ -1,7 +1,10 @@
{
"user_id": 1,
"username": "admin",
"display_name": "Admin",
"user": {
"id": 1,
"username": "admin",
"is_superuser": true,
"groups": []
},
"settings": {
"language": "",
"bulk_edit": {
@@ -30,5 +33,131 @@
"consumer_failed": true,
"consumer_suppress_on_dashboard": true
}
}
},
"permissions": [
"add_logentry",
"change_logentry",
"delete_logentry",
"view_logentry",
"add_group",
"change_group",
"delete_group",
"view_group",
"add_permission",
"change_permission",
"delete_permission",
"view_permission",
"add_user",
"change_user",
"delete_user",
"view_user",
"add_token",
"change_token",
"delete_token",
"view_token",
"add_tokenproxy",
"change_tokenproxy",
"delete_tokenproxy",
"view_tokenproxy",
"add_contenttype",
"change_contenttype",
"delete_contenttype",
"view_contenttype",
"add_chordcounter",
"change_chordcounter",
"delete_chordcounter",
"view_chordcounter",
"add_groupresult",
"change_groupresult",
"delete_groupresult",
"view_groupresult",
"add_taskresult",
"change_taskresult",
"delete_taskresult",
"view_taskresult",
"add_failure",
"change_failure",
"delete_failure",
"view_failure",
"add_ormq",
"change_ormq",
"delete_ormq",
"view_ormq",
"add_schedule",
"change_schedule",
"delete_schedule",
"view_schedule",
"add_success",
"change_success",
"delete_success",
"view_success",
"add_task",
"change_task",
"delete_task",
"view_task",
"add_note",
"change_note",
"delete_note",
"view_note",
"add_correspondent",
"change_correspondent",
"delete_correspondent",
"view_correspondent",
"add_document",
"change_document",
"delete_document",
"view_document",
"add_documenttype",
"change_documenttype",
"delete_documenttype",
"view_documenttype",
"add_frontendsettings",
"change_frontendsettings",
"delete_frontendsettings",
"view_frontendsettings",
"add_log",
"change_log",
"delete_log",
"view_log",
"add_paperlesstask",
"change_paperlesstask",
"delete_paperlesstask",
"view_paperlesstask",
"add_savedview",
"change_savedview",
"delete_savedview",
"view_savedview",
"add_savedviewfilterrule",
"change_savedviewfilterrule",
"delete_savedviewfilterrule",
"view_savedviewfilterrule",
"add_storagepath",
"change_storagepath",
"delete_storagepath",
"view_storagepath",
"add_tag",
"change_tag",
"delete_tag",
"view_tag",
"add_taskattributes",
"change_taskattributes",
"delete_taskattributes",
"view_taskattributes",
"add_uisettings",
"change_uisettings",
"delete_uisettings",
"view_uisettings",
"add_mailaccount",
"change_mailaccount",
"delete_mailaccount",
"view_mailaccount",
"add_mailrule",
"change_mailrule",
"delete_mailrule",
"view_mailrule",
"add_session",
"change_session",
"delete_session",
"view_session"
]
}

View File

@@ -0,0 +1,88 @@
{
"user": {
"id": 1,
"username": "admin",
"is_superuser": false,
"groups": []
},
"settings": {
"language": "",
"bulk_edit": {
"confirmation_dialogs": true,
"apply_on_close": false
},
"documentListSize": 50,
"dark_mode": {
"use_system": true,
"enabled": "false",
"thumb_inverted": "true"
},
"theme": {
"color": "#b198e5"
},
"document_details": {
"native_pdf_viewer": false
},
"date_display": {
"date_locale": "",
"date_format": "mediumDate"
},
"notifications": {
"consumer_new_documents": true,
"consumer_success": true,
"consumer_failed": true,
"consumer_suppress_on_dashboard": true
}
},
"permissions": [
"add_token",
"change_token",
"delete_token",
"view_token",
"add_tokenproxy",
"change_tokenproxy",
"delete_tokenproxy",
"view_tokenproxy",
"add_contenttype",
"change_contenttype",
"delete_contenttype",
"view_contenttype",
"add_chordcounter",
"change_chordcounter",
"delete_chordcounter",
"view_chordcounter",
"add_groupresult",
"change_groupresult",
"delete_groupresult",
"view_groupresult",
"add_failure",
"change_failure",
"delete_failure",
"view_failure",
"add_ormq",
"change_ormq",
"delete_ormq",
"view_ormq",
"add_schedule",
"change_schedule",
"delete_schedule",
"view_schedule",
"add_success",
"change_success",
"delete_success",
"view_success",
"add_task",
"change_task",
"delete_task",
"view_task",
"add_note",
"add_frontendsettings",
"change_frontendsettings",
"delete_frontendsettings",
"view_frontendsettings",
"add_session",
"change_session",
"delete_session",
"view_session"
]
}

View File

@@ -0,0 +1,459 @@
{
"count": 4,
"next": null,
"previous": null,
"results": [
{
"id": 3,
"username": "admin",
"password": "**********",
"first_name": "",
"last_name": "",
"date_joined": "2022-02-14T23:11:09.103293Z",
"is_staff": true,
"is_active": true,
"is_superuser": true,
"groups": [],
"user_permissions": [],
"inherited_permissions": [
"auth.delete_permission",
"paperless_mail.change_mailrule",
"django_celery_results.add_taskresult",
"documents.view_taskattributes",
"documents.view_paperlesstask",
"django_q.add_success",
"documents.view_uisettings",
"auth.change_user",
"admin.delete_logentry",
"django_celery_results.change_taskresult",
"django_q.change_schedule",
"django_celery_results.delete_taskresult",
"paperless_mail.add_mailaccount",
"auth.change_group",
"documents.add_note",
"paperless_mail.delete_mailaccount",
"authtoken.delete_tokenproxy",
"guardian.delete_groupobjectpermission",
"contenttypes.delete_contenttype",
"documents.change_correspondent",
"authtoken.delete_token",
"documents.delete_documenttype",
"django_q.change_ormq",
"documents.change_savedviewfilterrule",
"auth.delete_group",
"documents.add_documenttype",
"django_q.change_success",
"documents.delete_tag",
"documents.change_note",
"django_q.delete_task",
"documents.add_savedviewfilterrule",
"django_q.view_task",
"paperless_mail.add_mailrule",
"paperless_mail.view_mailaccount",
"documents.add_frontendsettings",
"sessions.change_session",
"documents.view_savedview",
"authtoken.add_tokenproxy",
"documents.change_tag",
"documents.view_document",
"documents.add_savedview",
"auth.delete_user",
"documents.view_log",
"documents.view_note",
"guardian.change_groupobjectpermission",
"sessions.delete_session",
"django_q.change_failure",
"guardian.change_userobjectpermission",
"documents.change_storagepath",
"documents.delete_document",
"documents.delete_taskattributes",
"django_celery_results.change_groupresult",
"django_q.add_ormq",
"guardian.view_groupobjectpermission",
"admin.change_logentry",
"django_q.delete_schedule",
"documents.delete_paperlesstask",
"django_q.view_ormq",
"documents.change_paperlesstask",
"guardian.delete_userobjectpermission",
"auth.view_permission",
"auth.view_user",
"django_q.add_schedule",
"authtoken.change_token",
"guardian.add_groupobjectpermission",
"documents.view_documenttype",
"documents.change_log",
"paperless_mail.delete_mailrule",
"auth.view_group",
"authtoken.view_token",
"admin.view_logentry",
"django_celery_results.view_chordcounter",
"django_celery_results.view_groupresult",
"documents.view_storagepath",
"documents.add_storagepath",
"django_celery_results.add_groupresult",
"documents.view_tag",
"guardian.view_userobjectpermission",
"documents.delete_correspondent",
"documents.add_tag",
"documents.delete_savedviewfilterrule",
"documents.add_correspondent",
"authtoken.view_tokenproxy",
"documents.delete_frontendsettings",
"django_celery_results.delete_chordcounter",
"django_q.change_task",
"documents.add_taskattributes",
"documents.delete_storagepath",
"sessions.add_session",
"documents.add_uisettings",
"documents.change_taskattributes",
"documents.delete_uisettings",
"django_q.delete_ormq",
"auth.change_permission",
"documents.view_savedviewfilterrule",
"documents.change_frontendsettings",
"documents.change_documenttype",
"documents.view_correspondent",
"auth.add_user",
"paperless_mail.change_mailaccount",
"documents.add_paperlesstask",
"django_q.view_success",
"django_celery_results.delete_groupresult",
"documents.delete_savedview",
"authtoken.change_tokenproxy",
"documents.view_frontendsettings",
"authtoken.add_token",
"django_celery_results.add_chordcounter",
"contenttypes.change_contenttype",
"admin.add_logentry",
"django_q.delete_failure",
"documents.change_uisettings",
"django_q.view_failure",
"documents.add_log",
"documents.change_savedview",
"paperless_mail.view_mailrule",
"django_q.view_schedule",
"documents.change_document",
"django_celery_results.change_chordcounter",
"documents.add_document",
"django_celery_results.view_taskresult",
"contenttypes.add_contenttype",
"django_q.delete_success",
"documents.delete_note",
"django_q.add_failure",
"guardian.add_userobjectpermission",
"sessions.view_session",
"contenttypes.view_contenttype",
"auth.add_permission",
"documents.delete_log",
"django_q.add_task",
"auth.add_group"
]
},
{
"id": 15,
"username": "test",
"password": "**********",
"first_name": "",
"last_name": "",
"date_joined": "2022-11-23T08:30:54Z",
"is_staff": true,
"is_active": true,
"is_superuser": false,
"groups": [
1
],
"user_permissions": [
"add_group",
"change_group",
"delete_group",
"view_group",
"add_permission",
"change_permission",
"delete_permission",
"view_permission",
"add_token",
"change_token",
"delete_token",
"view_token",
"add_tokenproxy",
"change_tokenproxy",
"delete_tokenproxy",
"view_tokenproxy",
"add_contenttype",
"change_contenttype",
"delete_contenttype",
"view_contenttype",
"add_chordcounter",
"change_chordcounter",
"delete_chordcounter",
"view_chordcounter",
"add_groupresult",
"change_groupresult",
"delete_groupresult",
"view_groupresult",
"add_taskresult",
"change_taskresult",
"delete_taskresult",
"view_taskresult",
"add_failure",
"change_failure",
"delete_failure",
"view_failure",
"add_ormq",
"change_ormq",
"delete_ormq",
"view_ormq",
"add_schedule",
"change_schedule",
"delete_schedule",
"view_schedule",
"add_success",
"change_success",
"delete_success",
"view_success",
"add_task",
"change_task",
"delete_task",
"view_task",
"add_note",
"change_note",
"delete_note",
"view_note",
"add_frontendsettings",
"change_frontendsettings",
"delete_frontendsettings",
"view_frontendsettings",
"add_log",
"change_log",
"delete_log",
"view_log",
"add_savedviewfilterrule",
"change_savedviewfilterrule",
"delete_savedviewfilterrule",
"view_savedviewfilterrule",
"add_taskattributes",
"change_taskattributes",
"delete_taskattributes",
"view_taskattributes",
"add_session",
"change_session",
"delete_session",
"view_session"
],
"inherited_permissions": [
"auth.delete_permission",
"django_celery_results.add_taskresult",
"documents.view_taskattributes",
"django_q.add_ormq",
"django_q.add_success",
"django_q.delete_schedule",
"django_q.view_ormq",
"auth.view_permission",
"django_q.add_schedule",
"django_celery_results.change_taskresult",
"django_q.change_schedule",
"django_celery_results.delete_taskresult",
"authtoken.change_token",
"auth.change_group",
"documents.add_note",
"authtoken.delete_tokenproxy",
"documents.view_documenttype",
"contenttypes.delete_contenttype",
"documents.change_correspondent",
"authtoken.delete_token",
"documents.change_log",
"auth.view_group",
"authtoken.view_token",
"django_celery_results.view_chordcounter",
"django_celery_results.view_groupresult",
"documents.delete_documenttype",
"django_q.change_ormq",
"documents.change_savedviewfilterrule",
"django_celery_results.add_groupresult",
"auth.delete_group",
"documents.add_documenttype",
"django_q.change_success",
"auth.add_permission",
"documents.delete_correspondent",
"documents.delete_savedviewfilterrule",
"documents.add_correspondent",
"authtoken.view_tokenproxy",
"documents.delete_frontendsettings",
"django_celery_results.delete_chordcounter",
"documents.add_taskattributes",
"django_q.change_task",
"sessions.add_session",
"documents.change_taskattributes",
"documents.change_note",
"django_q.delete_task",
"django_q.delete_ormq",
"auth.change_permission",
"documents.add_savedviewfilterrule",
"django_q.view_task",
"documents.view_savedviewfilterrule",
"documents.change_frontendsettings",
"documents.change_documenttype",
"documents.view_correspondent",
"django_q.view_success",
"documents.add_frontendsettings",
"django_celery_results.delete_groupresult",
"documents.delete_savedview",
"authtoken.change_tokenproxy",
"documents.view_frontendsettings",
"authtoken.add_token",
"sessions.change_session",
"django_celery_results.add_chordcounter",
"documents.view_savedview",
"contenttypes.change_contenttype",
"django_q.delete_failure",
"authtoken.add_tokenproxy",
"documents.view_document",
"documents.add_savedview",
"django_q.view_failure",
"documents.view_note",
"documents.view_log",
"documents.add_log",
"documents.change_savedview",
"django_q.view_schedule",
"documents.change_document",
"django_celery_results.change_chordcounter",
"documents.add_document",
"sessions.delete_session",
"django_q.change_failure",
"django_celery_results.view_taskresult",
"contenttypes.add_contenttype",
"django_q.delete_success",
"documents.delete_note",
"django_q.add_failure",
"sessions.view_session",
"contenttypes.view_contenttype",
"documents.delete_taskattributes",
"documents.delete_document",
"documents.delete_log",
"django_q.add_task",
"django_celery_results.change_groupresult",
"auth.add_group"
]
},
{
"id": 6,
"username": "testuser",
"password": "**********",
"first_name": "",
"last_name": "",
"date_joined": "2022-11-16T04:14:20.484914Z",
"is_staff": false,
"is_active": true,
"is_superuser": false,
"groups": [
1,
6
],
"user_permissions": [
"add_logentry",
"change_logentry",
"delete_logentry",
"view_logentry"
],
"inherited_permissions": [
"auth.delete_permission",
"django_celery_results.add_taskresult",
"documents.view_taskattributes",
"django_q.add_ormq",
"django_q.add_success",
"django_q.delete_schedule",
"django_q.view_ormq",
"auth.change_user",
"auth.view_permission",
"auth.view_user",
"django_q.add_schedule",
"django_celery_results.change_taskresult",
"django_q.change_schedule",
"django_celery_results.delete_taskresult",
"authtoken.change_token",
"auth.change_group",
"documents.add_note",
"authtoken.delete_tokenproxy",
"documents.view_documenttype",
"contenttypes.delete_contenttype",
"documents.change_correspondent",
"authtoken.delete_token",
"documents.change_log",
"auth.view_group",
"authtoken.view_token",
"django_celery_results.view_chordcounter",
"django_celery_results.view_groupresult",
"documents.delete_documenttype",
"django_q.change_ormq",
"documents.change_savedviewfilterrule",
"django_celery_results.add_groupresult",
"auth.delete_group",
"documents.add_documenttype",
"django_q.change_success",
"auth.add_permission",
"documents.delete_correspondent",
"documents.delete_savedviewfilterrule",
"documents.add_correspondent",
"authtoken.view_tokenproxy",
"documents.delete_frontendsettings",
"django_celery_results.delete_chordcounter",
"documents.add_taskattributes",
"django_q.change_task",
"sessions.add_session",
"documents.change_taskattributes",
"documents.change_note",
"django_q.delete_task",
"django_q.delete_ormq",
"auth.change_permission",
"documents.add_savedviewfilterrule",
"django_q.view_task",
"documents.view_savedviewfilterrule",
"documents.change_frontendsettings",
"documents.change_documenttype",
"documents.view_correspondent",
"auth.add_user",
"django_q.view_success",
"documents.add_frontendsettings",
"django_celery_results.delete_groupresult",
"documents.delete_savedview",
"authtoken.change_tokenproxy",
"documents.view_frontendsettings",
"authtoken.add_token",
"sessions.change_session",
"django_celery_results.add_chordcounter",
"documents.view_savedview",
"contenttypes.change_contenttype",
"django_q.delete_failure",
"authtoken.add_tokenproxy",
"documents.view_document",
"documents.add_savedview",
"django_q.view_failure",
"documents.view_note",
"documents.view_log",
"auth.delete_user",
"documents.add_log",
"documents.change_savedview",
"django_q.view_schedule",
"documents.change_document",
"django_celery_results.change_chordcounter",
"documents.add_document",
"sessions.delete_session",
"django_q.change_failure",
"django_celery_results.view_taskresult",
"contenttypes.add_contenttype",
"django_q.delete_success",
"documents.delete_note",
"django_q.add_failure",
"sessions.view_session",
"contenttypes.view_contenttype",
"documents.delete_taskattributes",
"documents.delete_document",
"documents.delete_log",
"django_q.add_task",
"django_celery_results.change_groupresult",
"auth.add_group"
]
}
]
}

View File

@@ -5,6 +5,14 @@ beforeEach(() => {
fixture: 'ui_settings/settings.json',
}).as('ui-settings')
cy.intercept('http://localhost:8000/api/users/*', {
fixture: 'users/users.json',
})
cy.intercept('http://localhost:8000/api/groups/*', {
fixture: 'groups/groups.json',
})
cy.intercept('http://localhost:8000/api/remote_version/', {
fixture: 'remote_version/remote_version.json',
})

File diff suppressed because it is too large Load Diff

15221
src-ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,20 +13,21 @@
},
"private": true,
"dependencies": {
"@angular/common": "~15.1.0",
"@angular/compiler": "~15.1.0",
"@angular/core": "~15.1.0",
"@angular/forms": "~15.1.0",
"@angular/localize": "~15.1.0",
"@angular/platform-browser": "~15.1.0",
"@angular/platform-browser-dynamic": "~15.1.0",
"@angular/router": "~15.1.0",
"@angular/common": "~15.2.5",
"@angular/compiler": "~15.2.5",
"@angular/core": "~15.2.5",
"@angular/forms": "~15.2.5",
"@angular/localize": "~15.2.5",
"@angular/platform-browser": "~15.2.5",
"@angular/platform-browser-dynamic": "~15.2.5",
"@angular/router": "~15.2.5",
"@ng-bootstrap/ng-bootstrap": "^14.0.1",
"@ng-select/ng-select": "^10.0.1",
"@ng-select/ng-select": "^10.0.4",
"@ngneat/dirty-check-forms": "^3.0.3",
"@popperjs/core": "^2.11.6",
"bootstrap": "^5.2.3",
"file-saver": "^2.0.5",
"mime-names": "^1.0.0",
"ng2-pdf-viewer": "^9.1.2",
"ngx-color": "^8.0.3",
"ngx-cookie-service": "^15.0.0",
@@ -35,22 +36,22 @@
"rxjs": "^7.8.0",
"tslib": "^2.4.1",
"uuid": "^9.0.0",
"zone.js": "~0.11.8"
"zone.js": "~0.12.0"
},
"devDependencies": {
"@angular-builders/jest": "15.0.0",
"@angular-devkit/build-angular": "~15.1.0",
"@angular-eslint/builder": "15.1.0",
"@angular-eslint/eslint-plugin": "15.1.0",
"@angular-eslint/eslint-plugin-template": "15.1.0",
"@angular-eslint/schematics": "15.1.0",
"@angular-eslint/template-parser": "15.1.0",
"@angular/cli": "~15.1.0",
"@angular/compiler-cli": "~15.1.0",
"@angular-devkit/build-angular": "~15.2.4",
"@angular-eslint/builder": "15.2.1",
"@angular-eslint/eslint-plugin": "15.2.1",
"@angular-eslint/eslint-plugin-template": "15.2.1",
"@angular-eslint/schematics": "15.2.1",
"@angular-eslint/template-parser": "15.2.1",
"@angular/cli": "~15.2.4",
"@angular/compiler-cli": "~15.2.5",
"@types/jest": "28.1.6",
"@types/node": "^18.7.23",
"@typescript-eslint/eslint-plugin": "^5.43.0",
"@typescript-eslint/parser": "^5.43.0",
"@types/node": "^18.15.11",
"@typescript-eslint/eslint-plugin": "^5.57.0",
"@typescript-eslint/parser": "^5.54.0",
"concurrently": "7.4.0",
"eslint": "^8.31.0",
"jest": "28.1.3",

View File

@@ -14,8 +14,13 @@ import { DocumentAsnComponent } from './components/document-asn/document-asn.com
import { DirtyFormGuard } from './guards/dirty-form.guard'
import { StoragePathListComponent } from './components/manage/storage-path-list/storage-path-list.component'
import { TasksComponent } from './components/manage/tasks/tasks.component'
import { PermissionsGuard } from './guards/permissions.guard'
import { DirtyDocGuard } from './guards/dirty-doc.guard'
import { DirtySavedViewGuard } from './guards/dirty-saved-view.guard'
import {
PermissionAction,
PermissionType,
} from './services/permissions.service'
const routes: Routes = [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
@@ -29,28 +34,153 @@ const routes: Routes = [
path: 'documents',
component: DocumentListComponent,
canDeactivate: [DirtySavedViewGuard],
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.Document,
},
},
},
{
path: 'view/:id',
component: DocumentListComponent,
canDeactivate: [DirtySavedViewGuard],
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.SavedView,
},
},
},
{
path: 'documents/:id',
component: DocumentDetailComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.Document,
},
},
},
{
path: 'documents/:id/:section',
component: DocumentDetailComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.Document,
},
},
},
{
path: 'asn/:id',
component: DocumentAsnComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.Document,
},
},
},
{
path: 'tags',
component: TagListComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.Tag,
},
},
},
{
path: 'documenttypes',
component: DocumentTypeListComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.DocumentType,
},
},
},
{
path: 'correspondents',
component: CorrespondentListComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.Correspondent,
},
},
},
{
path: 'storagepaths',
component: StoragePathListComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.StoragePath,
},
},
},
{
path: 'logs',
component: LogsComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.Admin,
},
},
},
{ path: 'documents/:id', component: DocumentDetailComponent },
{ path: 'asn/:id', component: DocumentAsnComponent },
{ path: 'tags', component: TagListComponent },
{ path: 'documenttypes', component: DocumentTypeListComponent },
{ path: 'correspondents', component: CorrespondentListComponent },
{ path: 'storagepaths', component: StoragePathListComponent },
{ path: 'logs', component: LogsComponent },
{
path: 'settings',
component: SettingsComponent,
canDeactivate: [DirtyFormGuard],
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.UISettings,
},
},
},
{
path: 'settings/:section',
component: SettingsComponent,
canDeactivate: [DirtyFormGuard],
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.UISettings,
},
},
},
{
path: 'settings/:section',
component: SettingsComponent,
canDeactivate: [DirtyFormGuard],
},
{
path: 'tasks',
component: TasksComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.PaperlessTask,
},
},
},
{ path: 'tasks', component: TasksComponent },
],

View File

@@ -9,6 +9,11 @@ import { NgxFileDropEntry } from 'ngx-file-drop'
import { UploadDocumentsService } from './services/upload-documents.service'
import { TasksService } from './services/tasks.service'
import { TourService } from 'ngx-ui-tour-ng-bootstrap'
import {
PermissionAction,
PermissionsService,
PermissionType,
} from './services/permissions.service'
@Component({
selector: 'app-root',
@@ -32,7 +37,8 @@ export class AppComponent implements OnInit, OnDestroy {
private uploadDocumentsService: UploadDocumentsService,
private tasksService: TasksService,
public tourService: TourService,
private renderer: Renderer2
private renderer: Renderer2,
private permissionsService: PermissionsService
) {
let anyWindow = window as any
anyWindow.pdfWorkerSrc = 'assets/js/pdf.worker.min.js'
@@ -74,15 +80,28 @@ export class AppComponent implements OnInit, OnDestroy {
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: () => {
this.router.navigate(['documents', status.documentId])
},
})
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.Document
)
) {
this.toastService.show({
title: $localize`Document added`,
delay: 10000,
content: $localize`Document ${status.filename} was added to paperless.`,
actionName: $localize`Open document`,
action: () => {
this.router.navigate(['documents', status.documentId])
},
})
} else {
this.toastService.show({
title: $localize`Document added`,
delay: 10000,
content: $localize`Document ${status.filename} was added to paperless.`,
})
}
}
})
@@ -225,7 +244,13 @@ export class AppComponent implements OnInit, OnDestroy {
}
public get dragDropEnabled(): boolean {
return !this.router.url.includes('dashboard')
return (
!this.router.url.includes('dashboard') &&
this.permissionsService.currentUserCan(
PermissionAction.Add,
PermissionType.Document
)
)
}
public fileOver() {

View File

@@ -42,6 +42,7 @@ import { CheckComponent } from './components/common/input/check/check.component'
import { PasswordComponent } from './components/common/input/password/password.component'
import { SaveViewConfigDialogComponent } from './components/document-list/save-view-config-dialog/save-view-config-dialog.component'
import { TagsComponent } from './components/common/input/tags/tags.component'
import { IfPermissionsDirective } from './directives/if-permissions.directive'
import { SortableDirective } from './directives/sortable.directive'
import { CookieService } from 'ngx-cookie-service'
import { CsrfInterceptor } from './interceptors/csrf.interceptor'
@@ -69,7 +70,8 @@ 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 { DocumentCommentsComponent } from './components/document-comments/document-comments.component'
import { DocumentNotesComponent } from './components/document-notes/document-notes.component'
import { PermissionsGuard } from './guards/permissions.guard'
import { DirtyDocGuard } from './guards/dirty-doc.guard'
import { DirtySavedViewGuard } from './guards/dirty-saved-view.guard'
import { StoragePathListComponent } from './components/manage/storage-path-list/storage-path-list.component'
@@ -77,8 +79,15 @@ import { StoragePathEditDialogComponent } from './components/common/edit-dialog/
import { SettingsService } from './services/settings.service'
import { TasksComponent } from './components/manage/tasks/tasks.component'
import { TourNgBootstrapModule } from 'ngx-ui-tour-ng-bootstrap'
import { UserEditDialogComponent } from './components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component'
import { GroupEditDialogComponent } from './components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component'
import { PermissionsSelectComponent } from './components/common/permissions-select/permissions-select.component'
import { MailAccountEditDialogComponent } from './components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component'
import { MailRuleEditDialogComponent } from './components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component'
import { PermissionsUserComponent } from './components/common/input/permissions/permissions-user/permissions-user.component'
import { PermissionsGroupComponent } from './components/common/input/permissions/permissions-group/permissions-group.component'
import { IfOwnerDirective } from './directives/if-owner.directive'
import { IfObjectPermissionsDirective } from './directives/if-object-permissions.directive'
import localeAr from '@angular/common/locales/ar'
import localeBe from '@angular/common/locales/be'
@@ -100,6 +109,8 @@ import localeSr from '@angular/common/locales/sr'
import localeSv from '@angular/common/locales/sv'
import localeTr from '@angular/common/locales/tr'
import localeZh from '@angular/common/locales/zh'
import { PermissionsDialogComponent } from './components/common/permissions-dialog/permissions-dialog.component'
import { PermissionsFormComponent } from './components/common/input/permissions/permissions-form/permissions-form.component'
registerLocaleData(localeAr)
registerLocaleData(localeBe)
@@ -165,6 +176,7 @@ function initializeApp(settings: SettingsService) {
PasswordComponent,
SaveViewConfigDialogComponent,
TagsComponent,
IfPermissionsDirective,
SortableDirective,
SavedViewWidgetComponent,
StatisticsWidgetComponent,
@@ -184,10 +196,19 @@ function initializeApp(settings: SettingsService) {
DateComponent,
ColorComponent,
DocumentAsnComponent,
DocumentCommentsComponent,
DocumentNotesComponent,
TasksComponent,
UserEditDialogComponent,
GroupEditDialogComponent,
PermissionsSelectComponent,
MailAccountEditDialogComponent,
MailRuleEditDialogComponent,
PermissionsUserComponent,
PermissionsGroupComponent,
IfOwnerDirective,
IfObjectPermissionsDirective,
PermissionsDialogComponent,
PermissionsFormComponent,
],
imports: [
BrowserModule,
@@ -225,6 +246,7 @@ function initializeApp(settings: SettingsService) {
DocumentTitlePipe,
{ provide: NgbDateAdapter, useClass: ISODateAdapter },
{ provide: NgbDateParserFormatter, useClass: LocalizedDateParserFormatter },
PermissionsGuard,
DirtyDocGuard,
DirtySavedViewGuard,
],

View File

@@ -10,7 +10,7 @@
</svg>
<span class="ms-2" [class.visually-hidden]="slimSidebarEnabled" i18n="app title">Paperless-ngx</span>
</a>
<div class="search-form-container flex-grow-1 py-2 pb-3 pb-sm-2 px-3 ps-md-4 me-sm-auto order-3 order-sm-1">
<div class="search-form-container flex-grow-1 py-2 pb-3 pb-sm-2 px-3 ps-md-4 me-sm-auto order-3 order-sm-1" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.Document }">
<form (ngSubmit)="search()" class="form-inline flex-grow-1">
<svg width="1em" height="1em" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#search"/>
@@ -39,7 +39,7 @@
<p class="small mb-0 px-3 text-muted" i18n>Logged in as {{this.settingsService.displayName}}</p>
<div class="dropdown-divider"></div>
</div>
<a ngbDropdownItem class="nav-link" routerLink="settings" (click)="closeMenu()">
<a ngbDropdownItem class="nav-link" routerLink="settings" (click)="closeMenu()" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.UISettings }">
<svg class="sidebaricon me-2" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#gear"/>
</svg><ng-container i18n>Settings</ng-container>
@@ -72,7 +72,7 @@
</svg><span>&nbsp;<ng-container i18n>Dashboard</ng-container></span>
</a>
</li>
<li class="nav-item">
<li class="nav-item" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.Document }">
<a class="nav-link" routerLink="documents" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Documents" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#files"/>
@@ -80,79 +80,82 @@
</a>
</li>
</ul>
<div *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.SavedView }">
<h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted" *ngIf='savedViewService.loading || savedViewService.sidebarViews.length > 0'>
<span i18n>Saved views</span>
<div *ngIf="savedViewService.loading" class="spinner-border spinner-border-sm fw-normal ms-2" role="status"></div>
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item w-100" *ngFor="let view of savedViewService.sidebarViews">
<a class="nav-link" [class.text-truncate]="!slimSidebarEnabled" routerLink="view/{{view.id}}" routerLinkActive="active" (click)="closeMenu()" [ngbPopover]="view.name" [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#funnel"/>
</svg><span>&nbsp;{{view.name}}</span>
</a>
</li>
</ul>
</div>
<h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted" *ngIf='savedViewService.loading || savedViewService.sidebarViews.length > 0'>
<span i18n>Saved views</span>
<div *ngIf="savedViewService.loading" class="spinner-border spinner-border-sm fw-normal ms-2" role="status"></div>
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item w-100" *ngFor="let view of savedViewService.sidebarViews">
<a class="nav-link" [class.text-truncate]="!slimSidebarEnabled" routerLink="view/{{view.id}}" routerLinkActive="active" (click)="closeMenu()" [ngbPopover]="view.name" [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#funnel"/>
</svg><span>&nbsp;{{view.name}}</span>
</a>
</li>
</ul>
<h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted" *ngIf='openDocuments.length > 0'>
<span i18n>Open documents</span>
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item w-100" *ngFor='let d of openDocuments'>
<a class="nav-link" [class.text-truncate]="!slimSidebarEnabled" routerLink="documents/{{d.id}}" routerLinkActive="active" (click)="closeMenu()" [ngbPopover]="d.title | documentTitle" [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#file-text"/>
</svg><span>&nbsp;{{d.title | documentTitle}}</span>
<span class="close" (click)="closeDocument(d); $event.preventDefault()">
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-x" viewBox="0 0 16 16">
<div *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.Document }">
<h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted" *ngIf='openDocuments.length > 0'>
<span i18n>Open documents</span>
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item w-100" *ngFor='let d of openDocuments'>
<a class="nav-link" [class.text-truncate]="!slimSidebarEnabled" routerLink="documents/{{d.id}}" routerLinkActive="active" (click)="closeMenu()" [ngbPopover]="d.title | documentTitle" [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#file-text"/>
</svg><span>&nbsp;{{d.title | documentTitle}}</span>
<span class="close" (click)="closeDocument(d); $event.preventDefault()">
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-x" viewBox="0 0 16 16">
<use xlink:href="assets/bootstrap-icons.svg#x"/>
</svg>
</span>
</a>
</li>
<li class="nav-item w-100" *ngIf="openDocuments.length >= 1">
<a class="nav-link" [class.text-truncate]="!slimSidebarEnabled" [routerLink]="[]" (click)="closeAll()" ngbPopover="Close all" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#x"/>
</svg>
</span>
</a>
</li>
<li class="nav-item w-100" *ngIf="openDocuments.length >= 1">
<a class="nav-link" [class.text-truncate]="!slimSidebarEnabled" [routerLink]="[]" (click)="closeAll()" ngbPopover="Close all" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#x"/>
</svg><span>&nbsp;<ng-container i18n>Close all</ng-container></span>
</a>
</li>
</ul>
</svg><span>&nbsp;<ng-container i18n>Close all</ng-container></span>
</a>
</li>
</ul>
</div>
<h6 class="sidebar-heading px-3 mt-4 mb-1 text-muted">
<span i18n>Manage</span>
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item">
<li class="nav-item" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.Correspondent }">
<a class="nav-link" routerLink="correspondents" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Correspondents" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#person"/>
</svg><span>&nbsp;<ng-container i18n>Correspondents</ng-container></span>
</a>
</li>
<li class="nav-item" tourAnchor="tour.tags">
<li class="nav-item" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.Tag }" tourAnchor="tour.tags">
<a class="nav-link" routerLink="tags" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Tags" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#tags"/>
</svg><span>&nbsp;<ng-container i18n>Tags</ng-container></span>
</a>
</li>
<li class="nav-item">
<li class="nav-item" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.DocumentType }">
<a class="nav-link" routerLink="documenttypes" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Document types" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#hash"/>
</svg><span>&nbsp;<ng-container i18n>Document types</ng-container></span>
</a>
</li>
<li class="nav-item">
<li class="nav-item" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.StoragePath }">
<a class="nav-link" routerLink="storagepaths" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Storage paths" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#folder"/>
</svg><span>&nbsp;<ng-container i18n>Storage paths</ng-container></span>
</a>
</li>
<li class="nav-item" tourAnchor="tour.file-tasks">
<li class="nav-item" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.PaperlessTask }" tourAnchor="tour.file-tasks">
<a class="nav-link" routerLink="tasks" routerLinkActive="active" (click)="closeMenu()" ngbPopover="File Tasks" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<span *ngIf="tasksService.failedFileTasks.length > 0 && slimSidebarEnabled" class="badge bg-danger position-absolute top-0 end-0">{{tasksService.failedFileTasks.length}}</span>
<svg class="sidebaricon" fill="currentColor">
@@ -160,14 +163,14 @@
</svg><span>&nbsp;<ng-container i18n>File Tasks<span *ngIf="tasksService.failedFileTasks.length > 0"><span class="badge bg-danger ms-2">{{tasksService.failedFileTasks.length}}</span></span></ng-container></span>
</a>
</li>
<li class="nav-item">
<li class="nav-item" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.Admin }">
<a class="nav-link" routerLink="logs" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Logs" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#text-left"/>
</svg><span>&nbsp;<ng-container i18n>Logs</ng-container></span>
</a>
</li>
<li class="nav-item" tourAnchor="tour.settings">
<li class="nav-item" *appIfPermissions="{ action: PermissionAction.View, type: PermissionType.UISettings }" tourAnchor="tour.settings">
<a class="nav-link" routerLink="settings" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Settings" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#gear"/>

View File

@@ -26,13 +26,17 @@ import { TasksService } from 'src/app/services/tasks.service'
import { ComponentCanDeactivate } from 'src/app/guards/dirty-doc.guard'
import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
import { ToastService } from 'src/app/services/toast.service'
import { ComponentWithPermissions } from '../with-permissions/with-permissions.component'
@Component({
selector: 'app-app-frame',
templateUrl: './app-frame.component.html',
styleUrls: ['./app-frame.component.scss'],
})
export class AppFrameComponent implements OnInit, ComponentCanDeactivate {
export class AppFrameComponent
extends ComponentWithPermissions
implements OnInit, ComponentCanDeactivate
{
constructor(
public router: Router,
private activatedRoute: ActivatedRoute,
@@ -44,7 +48,9 @@ export class AppFrameComponent implements OnInit, ComponentCanDeactivate {
public settingsService: SettingsService,
public tasksService: TasksService,
private readonly toastService: ToastService
) {}
) {
super()
}
ngOnInit(): void {
if (this.settingsService.get(SETTINGS_KEYS.UPDATE_CHECKING_ENABLED)) {

View File

@@ -1,6 +1,6 @@
import { Component, EventEmitter, Input, Output } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { interval, Subject, switchMap, take } from 'rxjs'
import { interval, Subject, take } from 'rxjs'
@Component({
selector: 'app-confirm-dialog',

View File

@@ -5,10 +5,16 @@
</button>
</div>
<div class="modal-body">
<app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
<app-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></app-input-select>
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive" novalidate></app-input-check>
<div *appIfOwner="object">
<app-permissions-form [users]="users" accordion="true" formControlName="permissions_form"></app-permissions-form>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>

View File

@@ -5,6 +5,7 @@ import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
import { UserService } from 'src/app/services/rest/user.service'
@Component({
selector: 'app-correspondent-edit-dialog',
@@ -12,8 +13,12 @@ import { CorrespondentService } from 'src/app/services/rest/correspondent.servic
styleUrls: ['./correspondent-edit-dialog.component.scss'],
})
export class CorrespondentEditDialogComponent extends EditDialogComponent<PaperlessCorrespondent> {
constructor(service: CorrespondentService, activeModal: NgbActiveModal) {
super(service, activeModal)
constructor(
service: CorrespondentService,
activeModal: NgbActiveModal,
userService: UserService
) {
super(service, activeModal, userService)
}
getCreateTitle() {
@@ -30,6 +35,7 @@ export class CorrespondentEditDialogComponent extends EditDialogComponent<Paperl
matching_algorithm: new FormControl(DEFAULT_MATCHING_ALGORITHM),
match: new FormControl(''),
is_insensitive: new FormControl(true),
permissions_form: new FormControl(null),
})
}
}

View File

@@ -6,10 +6,16 @@
</div>
<div class="modal-body">
<app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
<app-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></app-input-select>
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
<div class="col">
<app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
<app-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></app-input-select>
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
</div>
<div *appIfOwner="object">
<app-permissions-form [users]="users" accordion="true" formControlName="permissions_form"></app-permissions-form>
</div>
</div>
<div class="modal-footer">

View File

@@ -5,6 +5,7 @@ import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
import { UserService } from 'src/app/services/rest/user.service'
@Component({
selector: 'app-document-type-edit-dialog',
@@ -12,8 +13,12 @@ import { DocumentTypeService } from 'src/app/services/rest/document-type.service
styleUrls: ['./document-type-edit-dialog.component.scss'],
})
export class DocumentTypeEditDialogComponent extends EditDialogComponent<PaperlessDocumentType> {
constructor(service: DocumentTypeService, activeModal: NgbActiveModal) {
super(service, activeModal)
constructor(
service: DocumentTypeService,
activeModal: NgbActiveModal,
userService: UserService
) {
super(service, activeModal, userService)
}
getCreateTitle() {
@@ -30,6 +35,7 @@ export class DocumentTypeEditDialogComponent extends EditDialogComponent<Paperle
matching_algorithm: new FormControl(DEFAULT_MATCHING_ALGORITHM),
match: new FormControl(''),
is_insensitive: new FormControl(true),
permissions_form: new FormControl(null),
})
}
}

View File

@@ -2,19 +2,31 @@ import { Directive, EventEmitter, Input, OnInit, Output } from '@angular/core'
import { FormGroup } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { Observable } from 'rxjs'
import { MATCHING_ALGORITHMS, MATCH_AUTO } from 'src/app/data/matching-model'
import {
MATCHING_ALGORITHMS,
MATCH_AUTO,
MATCH_NONE,
} from 'src/app/data/matching-model'
import { ObjectWithId } from 'src/app/data/object-with-id'
import { ObjectWithPermissions } from 'src/app/data/object-with-permissions'
import { PaperlessUser } from 'src/app/data/paperless-user'
import { AbstractPaperlessService } from 'src/app/services/rest/abstract-paperless-service'
import { UserService } from 'src/app/services/rest/user.service'
import { PermissionsFormObject } from '../input/permissions/permissions-form/permissions-form.component'
@Directive()
export abstract class EditDialogComponent<T extends ObjectWithId>
implements OnInit
export abstract class EditDialogComponent<
T extends ObjectWithPermissions | ObjectWithId
> implements OnInit
{
constructor(
private service: AbstractPaperlessService<T>,
private activeModal: NgbActiveModal
protected service: AbstractPaperlessService<T>,
private activeModal: NgbActiveModal,
private userService: UserService
) {}
users: PaperlessUser[]
@Input()
dialogMode: string = 'create'
@@ -36,6 +48,14 @@ export abstract class EditDialogComponent<T extends ObjectWithId>
ngOnInit(): void {
if (this.object != null) {
if (this.object['permissions']) {
this.object['set_permissions'] = this.object['permissions']
}
this.object['permissions_form'] = {
owner: (this.object as ObjectWithPermissions).owner,
set_permissions: (this.object as ObjectWithPermissions).permissions,
}
this.objectForm.patchValue(this.object)
}
@@ -43,6 +63,8 @@ export abstract class EditDialogComponent<T extends ObjectWithId>
setTimeout(() => {
this.closeEnabled = true
})
this.userService.listAll().subscribe((r) => (this.users = r.results))
}
getCreateTitle() {
@@ -73,14 +95,24 @@ export abstract class EditDialogComponent<T extends ObjectWithId>
}
get patternRequired(): boolean {
return this.objectForm?.value.matching_algorithm !== MATCH_AUTO
return (
this.objectForm?.value.matching_algorithm !== MATCH_AUTO &&
this.objectForm?.value.matching_algorithm !== MATCH_NONE
)
}
save() {
var newObject = Object.assign(
Object.assign({}, this.object),
this.objectForm.value
)
this.error = null
const formValues = Object.assign({}, this.objectForm.value)
const permissionsObject: PermissionsFormObject =
this.objectForm.get('permissions_form')?.value
if (permissionsObject) {
formValues.owner = permissionsObject.owner
formValues.set_permissions = permissionsObject.set_permissions
delete formValues.permissions_form
}
var newObject = Object.assign(Object.assign({}, this.object), formValues)
var serverResponse: Observable<T>
switch (this.dialogMode) {
case 'create':
@@ -100,6 +132,7 @@ export abstract class EditDialogComponent<T extends ObjectWithId>
error: (error) => {
this.error = error.error
this.networkActive = false
this.succeeded.next(error)
},
})
}

View File

@@ -0,0 +1,19 @@
<form [formGroup]="objectForm" (ngSubmit)="save()">
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">{{getTitle()}}</h4>
<button type="button" [disabled]="!closeEnabled" class="btn-close" aria-label="Close" (click)="cancel()">
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
<app-permissions-select i18n-title title="Permissions" formControlName="permissions" [error]="error?.permissions"></app-permissions-select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
<button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button>
</div>
</form>

View File

@@ -0,0 +1,37 @@
import { Component } from '@angular/core'
import { FormControl, FormGroup } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
import { PaperlessGroup } from 'src/app/data/paperless-group'
import { GroupService } from 'src/app/services/rest/group.service'
import { UserService } from 'src/app/services/rest/user.service'
@Component({
selector: 'app-group-edit-dialog',
templateUrl: './group-edit-dialog.component.html',
styleUrls: ['./group-edit-dialog.component.scss'],
})
export class GroupEditDialogComponent extends EditDialogComponent<PaperlessGroup> {
constructor(
service: GroupService,
activeModal: NgbActiveModal,
userService: UserService
) {
super(service, activeModal, userService)
}
getCreateTitle() {
return $localize`Create new user group`
}
getEditTitle() {
return $localize`Edit user group`
}
getForm(): FormGroup {
return new FormGroup({
name: new FormControl(''),
permissions: new FormControl(null),
})
}
}

View File

@@ -15,11 +15,22 @@
<div class="col">
<app-input-text i18n-title title="Username" formControlName="username" [error]="error?.username"></app-input-text>
<app-input-password i18n-title title="Password" formControlName="password" [error]="error?.password"></app-input-password>
<app-input-check i18n-title title="Password is token" i18n-hint hint="Check if the password above is a token used for authentication" formControlName="is_token" [error]="error?.is_token"></app-input-check>
<app-input-text i18n-title title="Character Set" formControlName="character_set" [error]="error?.character_set"></app-input-text>
</div>
</div>
</div>
<div class="modal-footer">
<div class="m-0 me-2">
<ngb-alert #testResultAlert *ngIf="testResult" [type]="testResult" class="mb-0 py-2" (closed)="testResult = null">{{testResultMessage}}</ngb-alert>
</div>
<button type="button" class="btn btn-outline-primary" (click)="test()" [disabled]="networkActive || testActive">
<ng-container *ngIf="testActive">
<div class="spinner-border spinner-border-sm me-2" role="status"></div>
<span class="visually-hidden mr-1" i18n>Loading...</span>
</ng-container>
<ng-container i18n>Test</ng-container>
</button>
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
<button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button>
</div>

View File

@@ -0,0 +1,4 @@
::ng-deep .alert-dismissible .btn-close {
padding-top: 0.75rem !important;
padding-bottom: 0.75rem !important;
}

View File

@@ -1,12 +1,13 @@
import { Component } from '@angular/core'
import { Component, ViewChild } from '@angular/core'
import { FormControl, FormGroup } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { NgbActiveModal, NgbAlert } from '@ng-bootstrap/ng-bootstrap'
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
import {
IMAPSecurity,
PaperlessMailAccount,
} from 'src/app/data/paperless-mail-account'
import { MailAccountService } from 'src/app/services/rest/mail-account.service'
import { UserService } from 'src/app/services/rest/user.service'
const IMAP_SECURITY_OPTIONS = [
{ id: IMAPSecurity.None, name: $localize`No encryption` },
@@ -20,8 +21,18 @@ const IMAP_SECURITY_OPTIONS = [
styleUrls: ['./mail-account-edit-dialog.component.scss'],
})
export class MailAccountEditDialogComponent extends EditDialogComponent<PaperlessMailAccount> {
constructor(service: MailAccountService, activeModal: NgbActiveModal) {
super(service, activeModal)
testActive: boolean = false
testResult: string
alertTimeout
@ViewChild('testResultAlert', { static: false }) testResultAlert: NgbAlert
constructor(
service: MailAccountService,
activeModal: NgbActiveModal,
userService: UserService
) {
super(service, activeModal, userService)
}
getCreateTitle() {
@@ -40,6 +51,7 @@ export class MailAccountEditDialogComponent extends EditDialogComponent<Paperles
imap_security: new FormControl(IMAPSecurity.SSL),
username: new FormControl(null),
password: new FormControl(null),
is_token: new FormControl(false),
character_set: new FormControl('UTF-8'),
})
}
@@ -47,4 +59,33 @@ export class MailAccountEditDialogComponent extends EditDialogComponent<Paperles
get imapSecurityOptions() {
return IMAP_SECURITY_OPTIONS
}
test() {
this.testActive = true
this.testResult = null
clearTimeout(this.alertTimeout)
const mailService = this.service as MailAccountService
const newObject = Object.assign(
Object.assign({}, this.object),
this.objectForm.value
)
mailService.test(newObject).subscribe({
next: (result: { success: boolean }) => {
this.testActive = false
this.testResult = result.success ? 'success' : 'danger'
this.alertTimeout = setTimeout(() => this.testResultAlert.close(), 5000)
},
error: (e) => {
this.testActive = false
this.testResult = 'danger'
this.alertTimeout = setTimeout(() => this.testResultAlert.close(), 5000)
},
})
}
get testResultMessage() {
return this.testResult === 'success'
? $localize`Successfully connected to the mail server`
: $localize`Unable to connect to the mail server`
}
}

View File

@@ -18,6 +18,7 @@
<div class="col">
<p class="small" i18n>Paperless will only process mails that match <em>all</em> of the filters specified below.</p>
<app-input-text i18n-title title="Filter from" formControlName="filter_from" [error]="error?.filter_from"></app-input-text>
<app-input-text i18n-title title="Filter to" formControlName="filter_to" [error]="error?.filter_to"></app-input-text>
<app-input-text i18n-title title="Filter subject" formControlName="filter_subject" [error]="error?.filter_subject"></app-input-text>
<app-input-text i18n-title title="Filter body" formControlName="filter_body" [error]="error?.filter_body"></app-input-text>
<app-input-text i18n-title title="Filter attachment filename" formControlName="filter_attachment_filename" i18n-hint hint="Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." [error]="error?.filter_attachment_filename"></app-input-text>

View File

@@ -18,6 +18,7 @@ import { CorrespondentService } from 'src/app/services/rest/correspondent.servic
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
import { MailAccountService } from 'src/app/services/rest/mail-account.service'
import { MailRuleService } from 'src/app/services/rest/mail-rule.service'
import { UserService } from 'src/app/services/rest/user.service'
const ATTACHMENT_TYPE_OPTIONS = [
{
@@ -113,9 +114,10 @@ export class MailRuleEditDialogComponent extends EditDialogComponent<PaperlessMa
activeModal: NgbActiveModal,
accountService: MailAccountService,
correspondentService: CorrespondentService,
documentTypeService: DocumentTypeService
documentTypeService: DocumentTypeService,
userService: UserService
) {
super(service, activeModal)
super(service, activeModal, userService)
accountService
.listAll()
@@ -147,6 +149,7 @@ export class MailRuleEditDialogComponent extends EditDialogComponent<PaperlessMa
account: new FormControl(null),
folder: new FormControl('INBOX'),
filter_from: new FormControl(null),
filter_to: new FormControl(null),
filter_subject: new FormControl(null),
filter_body: new FormControl(null),
filter_attachment_filename: new FormControl(null),

View File

@@ -6,16 +6,16 @@
</div>
<div class="modal-body">
<p *ngIf="this.dialogMode === 'edit'" i18n>
<em>Note that editing a path does not apply changes to stored files until you have run the 'document_renamer' utility. See the <a target="_blank" href="https://docs.paperless-ngx.com/administration/#renamer">documentation</a>.</em>
</p>
<app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
<app-input-text i18n-title title="Path" formControlName="path" [error]="error?.path" [hint]="pathHint"></app-input-text>
<app-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></app-input-select>
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
<div *appIfOwner="object">
<app-permissions-form [users]="users" accordion="true" formControlName="permissions_form"></app-permissions-form>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>

View File

@@ -5,6 +5,7 @@ import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path'
import { StoragePathService } from 'src/app/services/rest/storage-path.service'
import { UserService } from 'src/app/services/rest/user.service'
@Component({
selector: 'app-storage-path-edit-dialog',
@@ -12,8 +13,12 @@ import { StoragePathService } from 'src/app/services/rest/storage-path.service'
styleUrls: ['./storage-path-edit-dialog.component.scss'],
})
export class StoragePathEditDialogComponent extends EditDialogComponent<PaperlessStoragePath> {
constructor(service: StoragePathService, activeModal: NgbActiveModal) {
super(service, activeModal)
constructor(
service: StoragePathService,
activeModal: NgbActiveModal,
userService: UserService
) {
super(service, activeModal, userService)
}
get pathHint() {
@@ -41,6 +46,7 @@ export class StoragePathEditDialogComponent extends EditDialogComponent<Paperles
matching_algorithm: new FormControl(DEFAULT_MATCHING_ALGORITHM),
match: new FormControl(''),
is_insensitive: new FormControl(true),
permissions_form: new FormControl(null),
})
}
}

View File

@@ -13,6 +13,11 @@
<app-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></app-input-select>
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
<div *appIfOwner="object">
<app-permissions-form [users]="users" accordion="true" formControlName="permissions_form"></app-permissions-form>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>

View File

@@ -6,6 +6,7 @@ import { PaperlessTag } from 'src/app/data/paperless-tag'
import { TagService } from 'src/app/services/rest/tag.service'
import { randomColor } from 'src/app/utils/color'
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
import { UserService } from 'src/app/services/rest/user.service'
@Component({
selector: 'app-tag-edit-dialog',
@@ -13,8 +14,12 @@ import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
styleUrls: ['./tag-edit-dialog.component.scss'],
})
export class TagEditDialogComponent extends EditDialogComponent<PaperlessTag> {
constructor(service: TagService, activeModal: NgbActiveModal) {
super(service, activeModal)
constructor(
service: TagService,
activeModal: NgbActiveModal,
userService: UserService
) {
super(service, activeModal, userService)
}
getCreateTitle() {
@@ -33,6 +38,7 @@ export class TagEditDialogComponent extends EditDialogComponent<PaperlessTag> {
matching_algorithm: new FormControl(DEFAULT_MATCHING_ALGORITHM),
match: new FormControl(''),
is_insensitive: new FormControl(true),
permissions_form: new FormControl(null),
})
}
}

View File

@@ -0,0 +1,38 @@
<form [formGroup]="objectForm" (ngSubmit)="save()">
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">{{getTitle()}}</h4>
<button type="button" [disabled]="!closeEnabled" class="btn-close" aria-label="Close" (click)="cancel()">
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<app-input-text i18n-title title="Username" formControlName="username" [error]="error?.username"></app-input-text>
<app-input-text i18n-title title="Email" formControlName="email" [error]="error?.email"></app-input-text>
<app-input-password i18n-title title="Password" formControlName="password" [error]="error?.password"></app-input-password>
<app-input-text i18n-title title="First name" formControlName="first_name" [error]="error?.first_name"></app-input-text>
<app-input-text i18n-title title="Last name" formControlName="last_name" [error]="error?.first_name"></app-input-text>
<div class="mb-2">
<div class="form-check form-switch form-check-inline">
<input type="checkbox" class="form-check-input" id="is_active" formControlName="is_active">
<label class="form-check-label" for="is_active" i18n>Active</label>
</div>
<div class="form-check form-switch form-check-inline">
<input type="checkbox" class="form-check-input" id="is_superuser" formControlName="is_superuser" (change)="onToggleSuperUser()">
<label class="form-check-label" for="is_superuser"><ng-container i18n>Superuser</ng-container> <small class="form-text text-muted ms-1" i18n>(Grants all permissions and can view objects)</small></label>
</div>
</div>
<app-input-select i18n-title title="Groups" [items]="groups" multiple="true" formControlName="groups"></app-input-select>
</div>
<div class="col">
<app-permissions-select i18n-title title="Permissions" formControlName="user_permissions" [error]="error?.user_permissions" [inheritedPermissions]="inheritedPermissions"></app-permissions-select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
<button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button>
</div>
</form>

View File

@@ -0,0 +1,87 @@
import { Component, OnInit } from '@angular/core'
import { FormControl, FormGroup } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { first } from 'rxjs'
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
import { PaperlessGroup } from 'src/app/data/paperless-group'
import { PaperlessUser } from 'src/app/data/paperless-user'
import { GroupService } from 'src/app/services/rest/group.service'
import { UserService } from 'src/app/services/rest/user.service'
@Component({
selector: 'app-user-edit-dialog',
templateUrl: './user-edit-dialog.component.html',
styleUrls: ['./user-edit-dialog.component.scss'],
})
export class UserEditDialogComponent
extends EditDialogComponent<PaperlessUser>
implements OnInit
{
groups: PaperlessGroup[]
passwordIsSet: boolean = false
constructor(
service: UserService,
activeModal: NgbActiveModal,
groupsService: GroupService
) {
super(service, activeModal, service)
groupsService
.listAll()
.pipe(first())
.subscribe((result) => (this.groups = result.results))
}
ngOnInit(): void {
super.ngOnInit()
this.onToggleSuperUser()
}
getCreateTitle() {
return $localize`Create new user account`
}
getEditTitle() {
return $localize`Edit user account`
}
getForm(): FormGroup {
return new FormGroup({
username: new FormControl(''),
email: new FormControl(''),
password: new FormControl(null),
first_name: new FormControl(''),
last_name: new FormControl(''),
is_active: new FormControl(true),
is_superuser: new FormControl(false),
groups: new FormControl([]),
user_permissions: new FormControl([]),
})
}
onToggleSuperUser() {
if (this.objectForm.get('is_superuser').value) {
this.objectForm.get('user_permissions').disable()
} else {
this.objectForm.get('user_permissions').enable()
}
}
get inheritedPermissions(): string[] {
const groupsVal: Array<number> = this.objectForm.get('groups').value
if (!groupsVal) return []
else
return groupsVal.flatMap(
(id) => this.groups.find((g) => g.id == id)?.permissions
)
}
save(): void {
this.passwordIsSet =
this.objectForm.get('password').value?.toString().replaceAll('*', '')
.length > 0
super.save()
}
}

View File

@@ -1,21 +1,29 @@
<div class="btn-group w-100" ngbDropdown role="group" (openChange)="dropdownOpenChange($event)" #dropdown="ngbDropdown">
<button class="btn btn-sm" id="dropdown{{title}}" ngbDropdownToggle [ngClass]="!editing && selectionModel.selectionSize() > 0 ? 'btn-primary' : 'btn-outline-primary'">
<button class="btn btn-sm" id="dropdown_{{name}}" ngbDropdownToggle [ngClass]="!editing && selectionModel.selectionSize() > 0 ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled">
<svg class="toolbaricon" fill="currentColor">
<use attr.xlink:href="assets/bootstrap-icons.svg#{{icon}}" />
</svg>
<div class="d-none d-sm-inline">&nbsp;{{title}}</div>
<ng-container *ngIf="!editing && selectionModel.totalCount > 0">
<app-clearable-badge [number]="multiple ? selectionModel.totalCount : undefined" [selected]="!multiple && selectionModel.selectionSize() > 0" (cleared)="reset()"></app-clearable-badge>
<app-clearable-badge [number]="selectionModel.totalCount" [selected]="selectionModel.selectionSize() > 0" (cleared)="reset()"></app-clearable-badge>
</ng-container>
</button>
<div class="dropdown-menu py-0 shadow" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}">
<div class="dropdown-menu py-0 shadow" ngbDropdownMenu attr.aria-labelledby="dropdown_{{name}}">
<div class="list-group list-group-flush">
<div *ngIf="!editing && multiple" class="list-group-item d-flex">
<div class="btn-group btn-group-xs flex-fill">
<input [(ngModel)]="selectionModel.logicalOperator" [disabled]="!operatorToggleEnabled" (ngModelChange)="selectionModel.toggleOperator()" type="radio" class="btn-check" id="logicalOperatorAnd" value="and">
<label class="btn btn-outline-primary" for="logicalOperatorAnd" i18n>All</label>
<input [(ngModel)]="selectionModel.logicalOperator" [disabled]="!operatorToggleEnabled" (ngModelChange)="selectionModel.toggleOperator()" type="radio" class="btn-check" id="logicalOperatorOr" value="or">
<label class="btn btn-outline-primary" for="logicalOperatorOr" i18n>Any</label>
<div *ngIf="!editing && manyToOne" class="list-group-item d-flex">
<div class="btn-group btn-group-xs flex-fill" role="group">
<input [(ngModel)]="selectionModel.logicalOperator" [disabled]="!modifierToggleEnabled" (ngModelChange)="selectionModel.toggleOperator()" type="radio" class="btn-check" id="logicalOperatorAnd_{{name}}" name="logicalOperatorAnd_{{name}}" value="and">
<label class="btn btn-outline-primary" for="logicalOperatorAnd_{{name}}" i18n>All</label>
<input [(ngModel)]="selectionModel.logicalOperator" [disabled]="!modifierToggleEnabled" (ngModelChange)="selectionModel.toggleOperator()" type="radio" class="btn-check" id="logicalOperatorOr_{{name}}" name="logicalOperatorOr_{{name}}" value="or">
<label class="btn btn-outline-primary" for="logicalOperatorOr_{{name}}" i18n>Any</label>
</div>
</div>
<div *ngIf="!editing && !manyToOne" class="list-group-item d-flex">
<div class="btn-group btn-group-xs flex-fill" role="group">
<input [(ngModel)]="selectionModel.intersection" [disabled]="!modifierToggleEnabled" (ngModelChange)="selectionModel.toggleIntersection()" type="radio" class="btn-check" id="intersectionInclude_{{name}}" name="intersectionInclude_{{name}}" value="include">
<label class="btn btn-outline-primary" for="intersectionInclude_{{name}}" i18n>Include</label>
<input [(ngModel)]="selectionModel.intersection" [disabled]="!modifierToggleEnabled" (ngModelChange)="selectionModel.toggleIntersection()" type="radio" class="btn-check" id="intersectionExclude_{{name}}" name="intersectionExclude_{{name}}" value="exclude">
<label class="btn btn-outline-primary" for="intersectionExclude_{{name}}" i18n>Exclude</label>
</div>
</div>
<div class="list-group-item">
@@ -25,16 +33,16 @@
</div>
<div *ngIf="selectionModel.items" class="items">
<ng-container *ngFor="let item of selectionModel.itemsSorted | filter: filterText">
<app-toggleable-dropdown-button *ngIf="allowSelectNone || item.id" [item]="item" [state]="selectionModel.get(item.id)" (toggle)="selectionModel.toggle(item.id)" (exclude)="excludeClicked(item.id)"></app-toggleable-dropdown-button>
<app-toggleable-dropdown-button *ngIf="allowSelectNone || item.id" [item]="item" [state]="selectionModel.get(item.id)" [count]="getUpdatedDocumentCount(item.id)" (toggle)="selectionModel.toggle(item.id)" (exclude)="excludeClicked(item.id)" [disabled]="disabled"></app-toggleable-dropdown-button>
</ng-container>
</div>
<button *ngIf="editing" class="list-group-item list-group-item-action bg-light" (click)="applyClicked()" [disabled]="!modelIsDirty">
<button *ngIf="editing" class="list-group-item list-group-item-action bg-light" (click)="applyClicked()" [disabled]="!modelIsDirty || disabled">
<small class="ms-2" [ngClass]="{'fw-bold': modelIsDirty}" i18n>Apply</small>
<svg width="1.5em" height="1em" viewBox="0 0 16 16" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#arrow-right" />
</svg>
</button>
<div *ngIf="!editing && multiple" class="list-group-item list-group-item-note pt-1 pb-2">
<div *ngIf="!editing && manyToOne" class="list-group-item list-group-item-note pt-1 pb-2">
<small i18n>Click again to exclude items.</small>
</div>
</div>

View File

@@ -11,18 +11,32 @@ import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
import { ToggleableItemState } from './toggleable-dropdown-button/toggleable-dropdown-button.component'
import { MatchingModel } from 'src/app/data/matching-model'
import { Subject } from 'rxjs'
import { SelectionDataItem } from 'src/app/services/rest/document.service'
export interface ChangedItems {
itemsToAdd: MatchingModel[]
itemsToRemove: MatchingModel[]
}
export enum LogicalOperator {
And = 'and',
Or = 'or',
}
export enum Intersection {
Include = 'include',
Exclude = 'exclude',
}
export class FilterableDropdownSelectionModel {
changed = new Subject<FilterableDropdownSelectionModel>()
multiple = false
private _logicalOperator = 'and'
temporaryLogicalOperator = this._logicalOperator
manyToOne = false
singleSelect = false
private _logicalOperator: LogicalOperator = LogicalOperator.And
temporaryLogicalOperator: LogicalOperator = this._logicalOperator
private _intersection: Intersection = Intersection.Include
temporaryIntersection: Intersection = this._intersection
items: MatchingModel[] = []
@@ -85,7 +99,30 @@ export class FilterableDropdownSelectionModel {
(state != ToggleableItemState.Selected &&
state != ToggleableItemState.Excluded)
) {
this.temporarySelectionStates.set(id, ToggleableItemState.Selected)
if (this.manyToOne || this.singleSelect) {
this.temporarySelectionStates.set(id, ToggleableItemState.Selected)
if (this.singleSelect) {
for (let key of this.temporarySelectionStates.keys()) {
if (key != id) {
this.temporarySelectionStates.delete(key)
}
}
}
} else {
let newState =
this.intersection == Intersection.Include
? ToggleableItemState.Selected
: ToggleableItemState.Excluded
if (!id) newState = ToggleableItemState.Selected
if (
state == ToggleableItemState.Excluded &&
this.intersection == Intersection.Exclude
) {
newState = ToggleableItemState.NotSelected
}
this.temporarySelectionStates.set(id, newState)
}
} else if (
state == ToggleableItemState.Selected ||
state == ToggleableItemState.Excluded
@@ -93,14 +130,6 @@ export class FilterableDropdownSelectionModel {
this.temporarySelectionStates.delete(id)
}
if (!this.multiple) {
for (let key of this.temporarySelectionStates.keys()) {
if (key != id) {
this.temporarySelectionStates.delete(key)
}
}
}
if (!id) {
for (let key of this.temporarySelectionStates.keys()) {
if (key) {
@@ -118,19 +147,36 @@ export class FilterableDropdownSelectionModel {
exclude(id: number, fireEvent: boolean = true) {
let state = this.temporarySelectionStates.get(id)
if (state == null || state != ToggleableItemState.Excluded) {
this.temporarySelectionStates.set(id, ToggleableItemState.Excluded)
this.temporaryLogicalOperator = this._logicalOperator = 'and'
} else if (state == ToggleableItemState.Excluded) {
this.temporarySelectionStates.delete(id)
}
if (id && (state == null || state != ToggleableItemState.Excluded)) {
this.temporaryLogicalOperator = this._logicalOperator = this.manyToOne
? LogicalOperator.And
: LogicalOperator.Or
if (!this.multiple) {
for (let key of this.temporarySelectionStates.keys()) {
if (key != id) {
this.temporarySelectionStates.delete(key)
if (this.manyToOne || this.singleSelect) {
this.temporarySelectionStates.set(id, ToggleableItemState.Excluded)
if (this.singleSelect) {
for (let key of this.temporarySelectionStates.keys()) {
if (key != id) {
this.temporarySelectionStates.delete(key)
}
}
}
} else {
let newState =
this.intersection == Intersection.Include
? ToggleableItemState.Selected
: ToggleableItemState.Excluded
if (
state == ToggleableItemState.Selected &&
this.intersection == Intersection.Include
) {
newState = ToggleableItemState.NotSelected
}
this.temporarySelectionStates.set(id, newState)
}
} else if (!id || state == ToggleableItemState.Excluded) {
this.temporarySelectionStates.delete(id)
}
if (fireEvent) {
@@ -142,11 +188,11 @@ export class FilterableDropdownSelectionModel {
return this.selectionStates.get(id) || ToggleableItemState.NotSelected
}
get logicalOperator(): string {
get logicalOperator(): LogicalOperator {
return this.temporaryLogicalOperator
}
set logicalOperator(operator: string) {
set logicalOperator(operator: LogicalOperator) {
this.temporaryLogicalOperator = operator
}
@@ -154,6 +200,26 @@ export class FilterableDropdownSelectionModel {
this.changed.next(this)
}
get intersection(): Intersection {
return this.temporaryIntersection
}
set intersection(intersection: Intersection) {
this.temporaryIntersection = intersection
}
toggleIntersection() {
if (this.temporarySelectionStates.size === 0) return
let newState =
this.intersection == Intersection.Include
? ToggleableItemState.Selected
: ToggleableItemState.Excluded
this.temporarySelectionStates.forEach((state, key) => {
this.temporarySelectionStates.set(key, newState)
})
this.changed.next(this)
}
get(id: number) {
return (
this.temporarySelectionStates.get(id) || ToggleableItemState.NotSelected
@@ -170,7 +236,8 @@ export class FilterableDropdownSelectionModel {
clear(fireEvent = true) {
this.temporarySelectionStates.clear()
this.temporaryLogicalOperator = this._logicalOperator = 'and'
this.temporaryLogicalOperator = this._logicalOperator = LogicalOperator.And
this.temporaryIntersection = this._intersection = Intersection.Include
if (fireEvent) {
this.changed.next(this)
}
@@ -193,6 +260,8 @@ export class FilterableDropdownSelectionModel {
return true
} else if (this.temporaryLogicalOperator !== this._logicalOperator) {
return true
} else if (this.temporaryIntersection !== this._intersection) {
return true
} else {
return false
}
@@ -216,13 +285,18 @@ export class FilterableDropdownSelectionModel {
this.selectionStates.set(key, value)
})
this._logicalOperator = this.temporaryLogicalOperator
this._intersection = this.temporaryIntersection
}
reset() {
reset(complete: boolean = false) {
this.temporarySelectionStates.clear()
this.selectionStates.forEach((value, key) => {
this.temporarySelectionStates.set(key, value)
})
if (complete) {
this.selectionStates.clear()
} else {
this.selectionStates.forEach((value, key) => {
this.temporarySelectionStates.set(key, value)
})
}
}
diff(): ChangedItems {
@@ -268,14 +342,16 @@ export class FilterableDropdownComponent {
return this._selectionModel.items
}
_selectionModel = new FilterableDropdownSelectionModel()
_selectionModel: FilterableDropdownSelectionModel =
new FilterableDropdownSelectionModel()
@Input()
set selectionModel(model: FilterableDropdownSelectionModel) {
if (this.selectionModel) {
this.selectionModel.changed.complete()
model.items = this.selectionModel.items
model.multiple = this.selectionModel.multiple
model.manyToOne = this.selectionModel.manyToOne
model.singleSelect = this.editing && !this.selectionModel.manyToOne
}
model.changed.subscribe((updatedModel) => {
this.selectionModelChange.next(updatedModel)
@@ -291,12 +367,12 @@ export class FilterableDropdownComponent {
selectionModelChange = new EventEmitter<FilterableDropdownSelectionModel>()
@Input()
set multiple(value: boolean) {
this.selectionModel.multiple = value
set manyToOne(manyToOne: boolean) {
this.selectionModel.manyToOne = manyToOne
}
get multiple() {
return this.selectionModel.multiple
get manyToOne() {
return this.selectionModel.manyToOne
}
@Input()
@@ -317,23 +393,38 @@ export class FilterableDropdownComponent {
@Input()
applyOnClose = false
@Input()
disabled = false
@Output()
apply = new EventEmitter<ChangedItems>()
@Output()
opened = new EventEmitter()
get operatorToggleEnabled(): boolean {
return (
this.selectionModel.selectionSize() > 1 &&
this.selectionModel.getExcludedItems().length == 0
)
get modifierToggleEnabled(): boolean {
return this.manyToOne
? this.selectionModel.selectionSize() > 1 &&
this.selectionModel.getExcludedItems().length == 0
: !this.selectionModel.isNoneSelected()
}
@Input()
documentCounts: SelectionDataItem[]
get name(): string {
return this.title ? this.title.replace(/\s/g, '_').toLowerCase() : null
}
getUpdatedDocumentCount(id: number) {
if (this.documentCounts) {
return this.documentCounts.find((c) => c.id === id)?.document_count
}
}
modelIsDirty: boolean = false
constructor(private filterPipe: FilterPipe) {
this.selectionModel = new FilterableDropdownSelectionModel()
this.selectionModelChange.subscribe((updatedModel) => {
this.modelIsDirty = updatedModel.isDirty()
})
@@ -355,6 +446,7 @@ export class FilterableDropdownComponent {
}, 0)
if (this.editing) {
this.selectionModel.reset()
this.modelIsDirty = false
}
this.opened.next(this)
} else {
@@ -386,7 +478,7 @@ export class FilterableDropdownComponent {
}
reset() {
this.selectionModel.reset()
this.selectionModel.reset(true)
this.selectionModelChange.emit(this.selectionModel)
}
}

Some files were not shown because too many files have changed in this diff Show More