Compare commits

...

338 Commits

Author SHA1 Message Date
jonaswinkler
b7e570aba0 Merge branch 'dev' 2021-03-18 19:41:45 +01:00
jonaswinkler
ce2bae12af changelog and version bump 2021-03-18 19:13:45 +01:00
Jonas Winkler
b6111d8da6 New Crowdin updates (#788) 2021-03-18 16:22:45 +01:00
jonaswinkler
2fb1132b69 fix test case 2021-03-17 23:08:19 +01:00
jonaswinkler
9a04bc1beb fixes #771 2021-03-17 22:57:37 +01:00
jonaswinkler
b39c3f7866 fixes #668 (see https://github.com/the-paperless-project/paperless/pull/571) 2021-03-17 22:44:18 +01:00
jonaswinkler
391db73ea8 added pt-pt locale 2021-03-17 22:32:39 +01:00
Jonas Winkler
4cd1672094 New Crowdin updates (#787) 2021-03-17 02:14:43 +01:00
jonaswinkler
6606d7572c API refactoring 2021-03-16 20:47:45 +01:00
Jonas Winkler
b331e3388f Merge pull request #778 from shamoon/fix/issue-774-775
Fix extra scrollbar on log container, auto scroll logs to bottom
2021-03-16 17:29:07 +01:00
Jonas Winkler
b6428aa85f Merge pull request #785 from isaacsando/master
update advanced_usage.rst to remove wording regarding filename parsing
2021-03-16 17:28:29 +01:00
isaacsando
fa6d554d1f update advanced_usage.rst to remove wording regarding filename parsing 2021-03-16 11:16:48 -05:00
Michael Shamoon
816871eed3 Redundant call to scroll 2021-03-16 03:08:48 -07:00
Michael Shamoon
ee04a9226b Don’t remove OnInit 2021-03-16 03:06:20 -07:00
Jonas Winkler
6b15093c43 New Crowdin updates (#776) 2021-03-16 10:40:38 +01:00
Michael Shamoon
b9d0954924 Automatically scroll log ouput 2021-03-15 09:56:17 -07:00
Michael Shamoon
a94a81d839 Revert "Reverse log order"
This reverts commit 2e21fbf619.
2021-03-15 08:45:33 -07:00
Michael Shamoon
46be3924e4 Revert "Side effecting"
This reverts commit 316a2469b8.
2021-03-15 08:45:30 -07:00
Michael Shamoon
316a2469b8 Side effecting 2021-03-15 08:42:10 -07:00
Michael Shamoon
2e21fbf619 Reverse log order 2021-03-15 08:38:55 -07:00
Michael Shamoon
e1254a053a Fix log container taller than viewport 2021-03-15 08:38:47 -07:00
Jonas Winkler
50bcd3daf1 New Crowdin updates (#764) 2021-03-15 10:48:25 +01:00
Jonas Winkler
7725973b62 Merge pull request #766 from shamoon/fix/additional-card-info-icons-fix
Fix additional card info icons sometimes cut off in certain browsers
2021-03-14 18:44:48 +01:00
Michael Shamoon
30bf7418f5 Dont change size overall 2021-03-14 09:35:53 -07:00
Michael Shamoon
eb611b2c41 Fix icons sometimes cut off in certain browsers 2021-03-14 09:33:57 -07:00
jonaswinkler
e4909c3133 Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-03-14 15:22:34 +01:00
jonaswinkler
2216330118 bump version 2021-03-14 15:22:25 +01:00
Jonas Winkler
ca090aa2fa New Crowdin updates (#763) 2021-03-14 15:12:10 +01:00
jonaswinkler
ec7ca2c352 changelog 2021-03-14 14:49:38 +01:00
jonaswinkler
2eb5e289ce optimized default thumbnail 2021-03-14 14:45:29 +01:00
jonaswinkler
40ce38254b fixes #631 2021-03-14 14:42:48 +01:00
jonaswinkler
0ad2b05455 fixes #745 2021-03-14 14:17:21 +01:00
jonaswinkler
c74d261f6a Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-03-14 14:06:27 +01:00
Jonas Winkler
68fe18fe36 Merge pull request #748 from shamoon/feature/additional-card-info
Additional / organized card info
2021-03-14 14:06:08 +01:00
jonaswinkler
47313db2c7 changelog 2021-03-14 14:01:43 +01:00
jonaswinkler
127129fbeb Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-03-14 13:34:31 +01:00
jonaswinkler
f43a8d6f2e Add spanish locale 2021-03-14 13:34:14 +01:00
Jonas Winkler
7cde850d98 New Crowdin updates (#757)
* New translations django.po (Spanish)
[ci skip]

* New translations messages.xlf (Spanish)
[ci skip]
2021-03-14 13:28:12 +01:00
Jonas Winkler
1bcfc5b54d New Crowdin updates (#752) 2021-03-13 23:19:03 +01:00
Michael Shamoon
7a8494da4d Small card tooltip tweaks, medium date 2021-03-12 20:15:18 -08:00
Michael Shamoon
65733863b1 tooltip placement 2021-03-12 20:12:05 -08:00
Michael Shamoon
e62ecefcd7 dark mode background color 2021-03-12 20:12:00 -08:00
Michael Shamoon
0aacebf783 Display date & ASN on one line if fits 2021-03-12 20:00:23 -08:00
Michael Shamoon
43b1700e91 hover color for card footer buttons 2021-03-12 19:59:45 -08:00
Michael Shamoon
9b4625b4a5 Fix pager color in dark mode 2021-03-12 19:52:31 -08:00
Michael Shamoon
27998df6e4 div instead of li 2021-03-12 19:35:25 -08:00
Michael Shamoon
eb5eabf3c6 fix text not visible in light mode on large card 2021-03-12 09:17:49 -08:00
Michael Shamoon
76cee78408 Visual tweaks for responsive 2021-03-12 08:12:36 -08:00
Michael Shamoon
0ba35a6eb5 More semantically correct elements 2021-03-12 07:58:37 -08:00
Michael Shamoon
6a58bd30ad Fix incomplete doc type clicking for large cards 2021-03-12 07:21:00 -08:00
Michael Shamoon
e71d055ef2 Tooltip consistency 2021-03-12 07:19:14 -08:00
Michael Shamoon
cb2eff47cc Refactor 2021-03-12 07:15:00 -08:00
Michael Shamoon
4696f9896b Support large cards 2021-03-12 06:54:22 -08:00
Jonas Winkler
424835880d New Crowdin updates (#738) 2021-03-12 15:53:37 +01:00
Jonas Winkler
e0e0ee4a77 Merge pull request #744 from shamoon/fix/miscellaneous-css-fixes
Fixes for mobile logger cut off & dark mode hidden "logged in as"
2021-03-12 15:48:16 +01:00
Michael Shamoon
5eca0ce554 Light mode fixes 2021-03-12 06:30:03 -08:00
Michael Shamoon
f5a06ac0dd Slightly shorter thumbnail 2021-03-12 06:11:53 -08:00
Michael Shamoon
81ea8873e0 Use medium date 2021-03-12 06:02:39 -08:00
Michael Shamoon
63b4ccacde Fix log lines hidden on narrow screens 2021-03-11 16:03:17 -08:00
Michael Shamoon
ccc39e0e55 Fix illegible logged in as in dark mode 2021-03-11 16:03:00 -08:00
Michael Shamoon
d264df1504 Additional metadata for small cards 2021-03-11 15:54:30 -08:00
jonaswinkler
9b7bc16b3e keep the ng2-pdf-viewer; this might come in handy for splitting documents at specific pages #706 2021-03-10 22:38:33 +01:00
jonaswinkler
f7f51f4f73 Merge branch 'dev' into feature/popover-previews 2021-03-10 22:32:37 +01:00
jonaswinkler
143ae1092c changelog 2021-03-10 22:31:49 +01:00
jonaswinkler
6470a443ac fix #735 2021-03-10 18:32:57 +01:00
jonaswinkler
7795baf989 change ISO date to always display 4 digit years #736 2021-03-10 18:15:23 +01:00
Jonas Winkler
5ab717c6be New Crowdin updates (#727) 2021-03-10 13:55:03 +01:00
Jonas Winkler
fac265486a Merge pull request #726 from darmiel/feature/664-filter-by-asn
Implemented 'Filter by: ASN'
2021-03-08 21:00:58 +01:00
darmiel
707efff644 Updated messages.xlf 2021-03-08 20:40:18 +01:00
Jonas Winkler
15291fd659 New Crowdin updates (#725) 2021-03-08 19:41:25 +01:00
darmiel
6535a20b21 Implemented 'Filter by: ASN' 2021-03-08 17:11:25 +01:00
Jonas Winkler
8c922dbffc Merge pull request #715 from rost314/fix_nfs_write_check
fix writable check for NFS mounts
2021-03-08 12:34:37 +01:00
Jonas Winkler
874f5fd2ca New Crowdin updates (#722) 2021-03-08 12:31:37 +01:00
Jonas Winkler
50864b10dd New Crowdin updates (#719)
New translations
2021-03-08 10:04:03 +01:00
Robert
57a5df1fce fix writable check for NFS mounts
For some reason, os.access(directory, os.W_OK | os.X_OK) does not work correctly on NFS mounts.
After some research, found out that the only secure and portable way to check for write access, is to touch a file.
2021-03-07 23:46:29 +01:00
Jonas Winkler
14828b15d8 New Crowdin updates (#718)
* New translations messages.xlf (English, United Kingdom)
[ci skip]

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

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

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

* New translations messages.xlf (English, United Kingdom)
[ci skip]

* New translations django.po (English, United Kingdom)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations messages.xlf (English, United Kingdom)
[ci skip]

* New translations django.po (English, United Kingdom)
[ci skip]

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations django.po (French)
[ci skip]
2021-03-07 22:37:04 +01:00
jonaswinkler
5f03e9e4cc Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-03-07 21:35:04 +01:00
jonaswinkler
c2b82fa063 fix up some messages 2021-03-07 21:34:55 +01:00
Jonas Winkler
40c4cfda75 Merge pull request #713 from jonaswinkler/l10n_dev
New Crowdin updates
2021-03-07 18:19:17 +01:00
Jonas Winkler
5c5ce6eedb New translations messages.xlf (Italian)
[ci skip]
2021-03-07 14:09:28 +01:00
Jonas Winkler
2fd1074729 New translations messages.xlf (Dutch)
[ci skip]
2021-03-07 13:11:07 +01:00
Jonas Winkler
2e379ad422 Merge pull request #712 from jonaswinkler/l10n_dev
New Crowdin updates
2021-03-07 12:27:43 +01:00
Jonas Winkler
c1cecb3e0e New translations messages.xlf (Dutch)
[ci skip]
2021-03-07 11:08:33 +01:00
Jonas Winkler
b0d13bed72 New translations messages.xlf (German)
[ci skip]
2021-03-07 11:08:32 +01:00
Jonas Winkler
d23a0d230c New translations django.po (German)
[ci skip]
2021-03-07 11:08:30 +01:00
Jonas Winkler
91b87f4e2c Merge pull request #711 from jonaswinkler/l10n_dev
New Crowdin updates
2021-03-07 11:06:08 +01:00
Jonas Winkler
a77c1f3ad1 New translations messages.xlf (Xhosa)
[ci skip]
2021-03-07 10:14:00 +01:00
Jonas Winkler
4c3cdaab0e New translations messages.xlf (French)
[ci skip]
2021-03-07 10:13:57 +01:00
Jonas Winkler
3e86c3d0d0 New translations messages.xlf (Spanish)
[ci skip]
2021-03-07 10:13:55 +01:00
Jonas Winkler
5a40d3c6fe New translations messages.xlf (Czech)
[ci skip]
2021-03-07 10:13:52 +01:00
Jonas Winkler
f79c1e0bcc New translations messages.xlf (German)
[ci skip]
2021-03-07 10:13:50 +01:00
Jonas Winkler
8f14ff7210 New translations messages.xlf (Hungarian)
[ci skip]
2021-03-07 10:13:48 +01:00
Jonas Winkler
90732d6a2f New translations messages.xlf (Italian)
[ci skip]
2021-03-07 10:13:46 +01:00
Jonas Winkler
f179ff9da4 New translations messages.xlf (Romanian)
[ci skip]
2021-03-07 10:13:44 +01:00
Jonas Winkler
90fd999220 New translations messages.xlf (Dutch)
[ci skip]
2021-03-07 10:13:43 +01:00
Jonas Winkler
04afbdd938 New translations messages.xlf (Portuguese)
[ci skip]
2021-03-07 10:13:41 +01:00
Jonas Winkler
5d3ef3d338 New translations messages.xlf (Russian)
[ci skip]
2021-03-07 10:13:39 +01:00
Jonas Winkler
4477d083e8 New translations messages.xlf (Chinese Simplified)
[ci skip]
2021-03-07 10:13:37 +01:00
Jonas Winkler
b7b3f54617 New translations messages.xlf (Portuguese, Brazilian)
[ci skip]
2021-03-07 10:13:35 +01:00
Jonas Winkler
5fc9f3f4da New translations messages.xlf (Thai)
[ci skip]
2021-03-07 10:13:32 +01:00
Jonas Winkler
c4b31f2f72 New translations messages.xlf (English, United Kingdom)
[ci skip]
2021-03-07 10:13:30 +01:00
Jonas Winkler
6c6b0511a6 New translations messages.xlf (Latin)
[ci skip]
2021-03-07 10:13:28 +01:00
jonaswinkler
6d20fc14ab updates messages 2021-03-07 10:08:45 +01:00
jonaswinkler
895c10600d add ru-ru locale 2021-03-07 10:07:42 +01:00
Jonas Winkler
c024efa578 Merge pull request #710 from jonaswinkler/l10n_dev
New Crowdin updates
2021-03-07 10:00:08 +01:00
Jonas Winkler
0022588b02 New translations messages.xlf (Russian)
[ci skip]
2021-03-07 02:58:09 +01:00
Jonas Winkler
47ec3d9149 New translations django.po (Russian)
[ci skip]
2021-03-07 02:58:08 +01:00
Jonas Winkler
811b82181d New translations messages.xlf (Russian)
[ci skip]
2021-03-07 01:59:13 +01:00
Jonas Winkler
32318ddbf6 Merge pull request #707 from jonaswinkler/l10n_dev
New Crowdin updates
2021-03-06 23:59:22 +01:00
Jonas Winkler
65a416fdae New translations django.po (French)
[ci skip]
2021-03-06 23:56:37 +01:00
Jonas Winkler
58d1f98368 New translations messages.xlf (French)
[ci skip]
2021-03-06 23:56:36 +01:00
Jonas Winkler
4cd7bf7123 New translations django.po (Spanish)
[ci skip]
2021-03-06 23:56:35 +01:00
Jonas Winkler
d4dea13eee New translations messages.xlf (Spanish)
[ci skip]
2021-03-06 23:56:34 +01:00
Jonas Winkler
507cdca757 New translations django.po (Czech)
[ci skip]
2021-03-06 23:56:33 +01:00
Jonas Winkler
27bfb2d3b0 New translations messages.xlf (Czech)
[ci skip]
2021-03-06 23:56:32 +01:00
Jonas Winkler
43118a1ffd New translations django.po (German)
[ci skip]
2021-03-06 23:56:30 +01:00
Jonas Winkler
729b305860 New translations messages.xlf (German)
[ci skip]
2021-03-06 23:56:29 +01:00
Jonas Winkler
72950d7872 New translations django.po (Hungarian)
[ci skip]
2021-03-06 23:56:28 +01:00
Jonas Winkler
364ffe8f38 New translations messages.xlf (Hungarian)
[ci skip]
2021-03-06 23:56:27 +01:00
Jonas Winkler
84d822b497 New translations django.po (Italian)
[ci skip]
2021-03-06 23:56:26 +01:00
Jonas Winkler
df99035c93 New translations messages.xlf (Italian)
[ci skip]
2021-03-06 23:56:25 +01:00
Jonas Winkler
63fc68cf83 New translations django.po (Dutch)
[ci skip]
2021-03-06 23:56:23 +01:00
Jonas Winkler
9c742fbf08 New translations messages.xlf (Romanian)
[ci skip]
2021-03-06 23:56:23 +01:00
Jonas Winkler
9965c35d2f New translations messages.xlf (Dutch)
[ci skip]
2021-03-06 23:56:21 +01:00
Jonas Winkler
0af567bc72 New translations messages.xlf (Portuguese)
[ci skip]
2021-03-06 23:56:20 +01:00
Jonas Winkler
0959a4e915 New translations django.po (Russian)
[ci skip]
2021-03-06 23:56:19 +01:00
Jonas Winkler
83be71f622 New translations messages.xlf (Russian)
[ci skip]
2021-03-06 23:56:18 +01:00
Jonas Winkler
9c985b36b3 New translations django.po (Chinese Simplified)
[ci skip]
2021-03-06 23:56:16 +01:00
Jonas Winkler
4ef0e20b5c New translations messages.xlf (Chinese Simplified)
[ci skip]
2021-03-06 23:56:15 +01:00
Jonas Winkler
d1cef044e5 New translations django.po (Portuguese, Brazilian)
[ci skip]
2021-03-06 23:56:14 +01:00
Jonas Winkler
f1d4860c79 New translations messages.xlf (Portuguese, Brazilian)
[ci skip]
2021-03-06 23:56:13 +01:00
Jonas Winkler
f1d6dd7d36 New translations django.po (English, United Kingdom)
[ci skip]
2021-03-06 23:56:08 +01:00
Jonas Winkler
46ae7f16dd New translations messages.xlf (English, United Kingdom)
[ci skip]
2021-03-06 23:56:07 +01:00
Jonas Winkler
5da441a001 New translations django.po (Portuguese)
[ci skip]
2021-03-06 23:56:05 +01:00
Jonas Winkler
d495bfab51 New translations django.po (Romanian)
[ci skip]
2021-03-06 23:56:03 +01:00
Michael Shamoon
4b4f3e76cc Re-merging this branch with Reverted dev 2021-03-06 14:50:38 -08:00
Michael Shamoon
ab0e97c1a0 Merge remote-tracking branch 'upstream/dev' into feature/popover-previews 2021-03-06 14:47:10 -08:00
jonaswinkler
381af329bd fix language codes 2021-03-06 23:40:29 +01:00
Michael Shamoon
4a0d17fc57 Merge branch 'feature/popover-previews' of https://github.com/shamoon/paperless-ng into feature/popover-previews 2021-03-06 14:39:53 -08:00
Michael Shamoon
e61f042547 Remove metadata API calls 2021-03-06 14:38:47 -08:00
Michael Shamoon
77815af5fb Update angular.json 2021-03-06 14:29:24 -08:00
jonaswinkler
e9cdb21164 Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-03-06 23:25:07 +01:00
Jonas Winkler
59bc467c50 Update README.md 2021-03-06 22:52:52 +01:00
Jonas Winkler
254dc62ca6 Update README.md 2021-03-06 22:50:35 +01:00
Jonas Winkler
253bde4e25 Merge pull request #705 from jonaswinkler/l10n_dev
New Crowdin updates
2021-03-06 22:47:27 +01:00
jonaswinkler
ea9e852216 fix a failing test case 2021-03-06 22:41:35 +01:00
Jonas Winkler
89150e99bf New translations messages.xlf (Xhosa)
[ci skip]
2021-03-06 22:40:29 +01:00
Jonas Winkler
5fd05f3d20 New translations django.po (French)
[ci skip]
2021-03-06 22:40:27 +01:00
Jonas Winkler
6c1a5f1a98 New translations messages.xlf (French)
[ci skip]
2021-03-06 22:40:26 +01:00
Jonas Winkler
7815a011af New translations django.po (Spanish)
[ci skip]
2021-03-06 22:40:25 +01:00
Jonas Winkler
efca0083bf New translations messages.xlf (Spanish)
[ci skip]
2021-03-06 22:40:24 +01:00
Jonas Winkler
4c983b0e25 New translations django.po (Czech)
[ci skip]
2021-03-06 22:40:23 +01:00
Jonas Winkler
d81f64ec06 New translations messages.xlf (Czech)
[ci skip]
2021-03-06 22:40:22 +01:00
Jonas Winkler
5735313392 New translations django.po (German)
[ci skip]
2021-03-06 22:40:20 +01:00
Jonas Winkler
259b2fe429 New translations messages.xlf (German)
[ci skip]
2021-03-06 22:40:19 +01:00
Jonas Winkler
bb739a55a5 New translations django.po (Hungarian)
[ci skip]
2021-03-06 22:40:18 +01:00
Jonas Winkler
7436b75566 New translations messages.xlf (Hungarian)
[ci skip]
2021-03-06 22:40:17 +01:00
Jonas Winkler
573ac882f5 New translations django.po (Italian)
[ci skip]
2021-03-06 22:40:15 +01:00
Jonas Winkler
7f70a886d5 New translations messages.xlf (Italian)
[ci skip]
2021-03-06 22:40:14 +01:00
Jonas Winkler
4a1c0c2971 New translations django.po (Dutch)
[ci skip]
2021-03-06 22:40:13 +01:00
Jonas Winkler
ad37ccd76d New translations messages.xlf (Dutch)
[ci skip]
2021-03-06 22:40:12 +01:00
Jonas Winkler
d3a4b17d59 New translations messages.xlf (Romanian)
[ci skip]
2021-03-06 22:40:10 +01:00
Jonas Winkler
4233d73569 New translations django.po (Portuguese)
[ci skip]
2021-03-06 22:40:09 +01:00
Jonas Winkler
6d9a0162b2 New translations django.po (Russian)
[ci skip]
2021-03-06 22:40:08 +01:00
Jonas Winkler
72f89de994 New translations messages.xlf (Russian)
[ci skip]
2021-03-06 22:40:07 +01:00
Jonas Winkler
bf01799d57 New translations django.po (Chinese Simplified)
[ci skip]
2021-03-06 22:40:05 +01:00
Jonas Winkler
6b63d3855b New translations messages.xlf (Chinese Simplified)
[ci skip]
2021-03-06 22:40:04 +01:00
Jonas Winkler
f0e0e780c5 New translations django.po (Portuguese, Brazilian)
[ci skip]
2021-03-06 22:40:03 +01:00
Jonas Winkler
646803b93e New translations messages.xlf (Portuguese, Brazilian)
[ci skip]
2021-03-06 22:40:02 +01:00
Jonas Winkler
3026b59af4 New translations django.po (Thai)
[ci skip]
2021-03-06 22:40:00 +01:00
Jonas Winkler
5adee00ca1 New translations messages.xlf (Thai)
[ci skip]
2021-03-06 22:39:59 +01:00
Jonas Winkler
47e887dac5 New translations django.po (English, United Kingdom)
[ci skip]
2021-03-06 22:39:58 +01:00
Jonas Winkler
70395a035c New translations messages.xlf (English, United Kingdom)
[ci skip]
2021-03-06 22:39:57 +01:00
Jonas Winkler
2f63dcb3b5 New translations django.po (Latin)
[ci skip]
2021-03-06 22:39:55 +01:00
Jonas Winkler
468ea09965 New translations messages.xlf (Latin)
[ci skip]
2021-03-06 22:39:54 +01:00
Jonas Winkler
b6a94d33b8 New translations django.po (Xhosa)
[ci skip]
2021-03-06 22:39:53 +01:00
Jonas Winkler
40c89a8a38 New translations messages.xlf (Portuguese)
[ci skip]
2021-03-06 22:39:52 +01:00
Jonas Winkler
92a61902b5 New translations django.po (Romanian)
[ci skip]
2021-03-06 22:39:51 +01:00
jonaswinkler
23ee01b1ce Merge branch 'crowdin-test' of github.com:jonaswinkler/paperless-ng into crowdin-test 2021-03-06 22:20:30 +01:00
jonaswinkler
fc727e0472 fix up language file locations 2021-03-06 22:20:06 +01:00
Jonas Winkler
9427c70b10 Update Crowdin configuration file 2021-03-06 22:13:12 +01:00
jonaswinkler
cba71ed8e0 fix config 2021-03-06 22:12:44 +01:00
jonaswinkler
728778bdf4 update crowdin.yml 2021-03-06 22:09:03 +01:00
Jonas Winkler
30a92e25c1 Merge pull request #703 from darmiel/patch-1
Installation Script: Check for Docker permissions on startup
2021-03-06 16:44:44 +01:00
Daniel
4862eb5e84 Use -e switch after docker permission check 2021-03-06 15:40:19 +01:00
Daniel
42fd62ecfd Changed spaces to tabs 2021-03-06 15:30:16 +01:00
Daniel
67437f7b9c Check if the user has permissions for Docker 2021-03-06 15:27:55 +01:00
jonaswinkler
6c961dfad9 Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-03-06 12:59:29 +01:00
Jonas Winkler
b0b5f9e0a1 Merge pull request #702 from auanasgheps/patch-1
Update Italian Translation
2021-03-06 12:58:49 +01:00
Oliver Cervera
69df7f8ef6 Update Italian Translation
Minor change to Italian translation.
Manual PR since Transifex doesn't do it.
2021-03-06 12:55:24 +01:00
jonaswinkler
0bb0fc5a19 changelog 2021-03-06 12:42:07 +01:00
jonaswinkler
be15e86458 added a test case for title_content filter 2021-03-06 12:41:59 +01:00
jonaswinkler
24eff6b02b documentation 2021-03-06 12:28:41 +01:00
jonaswinkler
ddb96829ca fix typo 2021-03-06 12:08:52 +01:00
jonaswinkler
4290f38e81 fix closing all documents from sidebar 2021-03-06 12:00:58 +01:00
jonaswinkler
ee4a5d53ad instructions on building the docker image 2021-03-06 11:47:11 +01:00
jonaswinkler
1f4d2e76d7 dark mode for color picker 2021-03-05 23:36:09 +01:00
jonaswinkler
9816efb816 Revert "Merge pull request #628 from shamoon/feature/popover-previews"
This reverts commit 8da1521508, reversing
changes made to a7846925b1.
2021-03-05 23:19:44 +01:00
Jonas Winkler
8da1521508 Merge pull request #628 from shamoon/feature/popover-previews
Feature: popover document previews
2021-03-05 21:34:19 +01:00
Jonas Winkler
a7846925b1 Merge pull request #699 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_en_GB
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'en_GB'
2021-03-05 09:36:52 +01:00
Jonas Winkler
d678bd71e8 Merge pull request #700 from jonaswinkler/translations_src-ui-messages-xlf--dev_en_GB
Translate '/src-ui/messages.xlf' in 'en_GB'
2021-03-05 09:36:39 +01:00
transifex-integration[bot]
67754efd36 Translate /src-ui/messages.xlf in en_GB
translation completed for the source file '/src-ui/messages.xlf'
on the 'en_GB' language.
2021-03-05 08:36:32 +00:00
transifex-integration[bot]
80e0fc21cc Apply translations in en_GB
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'en_GB' language.
2021-03-05 08:36:30 +00:00
Jonas Winkler
1025f6ccb5 Merge pull request #698 from siancu/dev
Postgres won't run without a password.
2021-03-04 16:44:49 +01:00
Stelian Iancu
ede06f4fd4 Postgres won't run without a password. 2021-03-04 16:26:03 +01:00
Jonas Winkler
6dd0de0201 Merge pull request #694 from jonaswinkler/translations_src-ui-messages-xlf--dev_nl_NL
Translate '/src-ui/messages.xlf' in 'nl_NL'
2021-03-04 11:32:56 +01:00
transifex-integration[bot]
7f01ead374 Translate /src-ui/messages.xlf in nl_NL
translation completed for the source file '/src-ui/messages.xlf'
on the 'nl_NL' language.
2021-03-04 10:25:24 +00:00
Michael Shamoon
cba507258d Merge remote-tracking branch 'upstream/dev' into feature/popover-previews 2021-03-03 21:19:51 -08:00
Michael Shamoon
ae93999f6a Simplify preview tooltip since its delayed 2021-03-03 21:14:24 -08:00
Michael Shamoon
1ff7a89a35 Larger popover preview size 2021-03-03 20:49:14 -08:00
Michael Shamoon
31cd32406c Refactor popover css to single file 2021-03-03 20:49:02 -08:00
Michael Shamoon
e5f750dcbe Fix double scrollbar, I think 2021-03-03 20:42:50 -08:00
jonaswinkler
59ecff8701 test case for the migration 2021-03-04 00:16:24 +01:00
jonaswinkler
80e91cde70 changelog 2021-03-04 00:10:15 +01:00
jonaswinkler
b1c2c79d80 update docs 2021-03-03 23:58:53 +01:00
jonaswinkler
5b2576ace4 remove test cases #677 2021-03-03 23:55:25 +01:00
Jonas Winkler
da9f370924 Merge pull request #677 from skuzzle/dev
Add the possibility to customize the remote user header name
2021-03-03 23:54:33 +01:00
jonaswinkler
e56daf07d4 Merge branch 'master' into dev 2021-03-03 23:46:37 +01:00
jonaswinkler
9e3caa57ec fix quoting 2021-03-03 23:44:43 +01:00
jonaswinkler
4fd7b9ef1f Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-03-03 23:44:15 +01:00
jonaswinkler
12235cc853 fixes #689 2021-03-03 23:35:26 +01:00
Jonas Winkler
56e4264394 Merge pull request #680 from jonaswinkler/translations_src-ui-messages-xlf--dev_it
Translate '/src-ui/messages.xlf' in 'it'
2021-03-03 09:39:50 +01:00
Jonas Winkler
baf8203b80 Merge pull request #681 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_it
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'it'
2021-03-03 09:39:39 +01:00
transifex-integration[bot]
41d966895f Apply translations in it
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'it' language.
2021-03-03 07:30:59 +00:00
transifex-integration[bot]
551792274f Translate /src-ui/messages.xlf in it
translation completed for the source file '/src-ui/messages.xlf'
on the 'it' language.
2021-03-03 07:30:31 +00:00
jonaswinkler
c7abdb61e8 added remote user auth test 2021-03-02 23:19:06 +01:00
Simon Taddiken
72ebe7df58 Improve documentation 2021-03-02 10:21:50 +01:00
Simon Taddiken
97f3c214e8 Add the possibility to customize the remote user header name
Inspired by the discussion here https://github.com/jonaswinkler/paperless-ng/discussions/639#discussion-3242017 it is worthwhile to be able to customize the header name that is used for authentication as its name is not really standardized.
2021-03-02 09:07:42 +01:00
Jonas Winkler
47842bac1c Merge pull request #665 from holzhannes/patch-1
Update to status of affiliateded projects
2021-03-02 00:39:13 +01:00
Jonas Winkler
ede498fa52 Merge pull request #671 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_nl_NL
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'nl_NL'
2021-03-01 16:37:53 +01:00
transifex-integration[bot]
c8a06416e7 Apply translations in nl_NL
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'nl_NL' language.
2021-03-01 15:30:27 +00:00
Jonas Winkler
5fea7f2bc4 Merge pull request #666 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_de
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'de'
2021-02-28 21:48:20 +01:00
Jonas Winkler
15420137fa Merge pull request #667 from jonaswinkler/translations_src-ui-messages-xlf--dev_de
Translate '/src-ui/messages.xlf' in 'de'
2021-02-28 21:48:10 +01:00
transifex-integration[bot]
73791e0e50 Translate /src-ui/messages.xlf in de
translation completed for the source file '/src-ui/messages.xlf'
on the 'de' language.
2021-02-28 20:47:42 +00:00
transifex-integration[bot]
7af0f12e6b Apply translations in de
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'de' language.
2021-02-28 20:47:14 +00:00
HolzHannes
895f9c911b Update to status of affiliateded projects 2021-02-28 20:23:38 +01:00
Jonas Winkler
204f47265b Merge pull request #663 from jonaswinkler/translations_src-ui-messages-xlf--dev_ro
Translate '/src-ui/messages.xlf' in 'ro'
2021-02-28 19:54:45 +01:00
transifex-integration[bot]
b240b4821a Translate /src-ui/messages.xlf in ro
translation completed for the source file '/src-ui/messages.xlf'
on the 'ro' language.
2021-02-28 18:04:39 +00:00
Jonas Winkler
249f6e4f27 Merge pull request #661 from jonaswinkler/translations_src-ui-messages-xlf--dev_pt_BR
Translate '/src-ui/messages.xlf' in 'pt_BR'
2021-02-28 18:02:10 +01:00
Jonas Winkler
32facd2877 Merge pull request #662 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_pt_BR
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'pt_BR'
2021-02-28 18:01:23 +01:00
transifex-integration[bot]
fd3cb6e2ca Apply translations in pt_BR
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'pt_BR' language.
2021-02-28 16:59:47 +00:00
transifex-integration[bot]
1df6d857e5 Translate /src-ui/messages.xlf in pt_BR
translation completed for the source file '/src-ui/messages.xlf'
on the 'pt_BR' language.
2021-02-28 16:59:35 +00:00
Jonas Winkler
3b9c2fd4d2 Merge pull request #660 from jonaswinkler/translations_src-ui-messages-xlf--dev_fr
Translate '/src-ui/messages.xlf' in 'fr'
2021-02-28 17:38:14 +01:00
Jonas Winkler
baa130e646 Merge pull request #659 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_fr
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'fr'
2021-02-28 17:38:04 +01:00
transifex-integration[bot]
c3ec40189f Translate /src-ui/messages.xlf in fr
translation completed for the source file '/src-ui/messages.xlf'
on the 'fr' language.
2021-02-28 16:36:24 +00:00
transifex-integration[bot]
686ae5b213 Apply translations in fr
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'fr' language.
2021-02-28 16:35:20 +00:00
jonaswinkler
5c19a8bb70 improved color generation logic 2021-02-28 16:35:02 +01:00
jonaswinkler
efa7b7b0b5 filter by title or title+content fixes #636 2021-02-28 16:19:41 +01:00
jonaswinkler
e466c31bb3 Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-02-28 13:39:17 +01:00
Jonas Winkler
942acf5940 Merge pull request #658 from jonaswinkler/translations_src-ui-messages-xlf--dev_ro
Translate '/src-ui/messages.xlf' in 'ro'
2021-02-28 13:39:01 +01:00
Jonas Winkler
b38d8d8640 Merge pull request #657 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_ro
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'ro'
2021-02-28 13:38:35 +01:00
transifex-integration[bot]
c4c8a96f25 Translate /src-ui/messages.xlf in ro
translation completed for the source file '/src-ui/messages.xlf'
on the 'ro' language.
2021-02-28 12:36:01 +00:00
transifex-integration[bot]
65377d881c Apply translations in ro
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'ro' language.
2021-02-28 12:35:21 +00:00
jonaswinkler
b847e0c65e changelog, documentation, version bump 2021-02-28 13:20:31 +01:00
jonaswinkler
6ab884a95c update dependencies 2021-02-28 13:01:26 +01:00
jonaswinkler
4b17a485ae update messages and typo fix 2021-02-28 12:42:46 +01:00
jonaswinkler
e5a4715161 add Romanian locale configuration 2021-02-28 12:40:25 +01:00
Jonas Winkler
53b7b14467 Merge pull request #656 from jonaswinkler/translations_src-ui-messages-xlf--dev_ro
Translate '/src-ui/messages.xlf' in 'ro'
2021-02-28 12:02:42 +01:00
transifex-integration[bot]
5eeb012557 Translate /src-ui/messages.xlf in ro
translation completed for the source file '/src-ui/messages.xlf'
on the 'ro' language.
2021-02-28 11:02:26 +00:00
Jonas Winkler
cf9884aaba Merge pull request #655 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_ro
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'ro'
2021-02-28 11:47:35 +01:00
transifex-integration[bot]
d811cab57e Apply translations in ro
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'ro' language.
2021-02-28 10:33:26 +00:00
jonaswinkler
d5a3443076 Merge branch 'fix/issue-603' into dev 2021-02-27 11:25:21 +01:00
jonaswinkler
bd11d3a34f small changes 2021-02-27 11:24:58 +01:00
jonaswinkler
5f6a202d65 Merge remote-tracking branch 'shamoon/fix/issue-603' into fix/issue-603 2021-02-27 11:13:21 +01:00
jonaswinkler
6db3f7023f remove unused files 2021-02-26 23:24:13 +01:00
Michael Shamoon
8a64898798 TypeScript fixes 2021-02-26 14:16:31 -08:00
Michael Shamoon
6ad14d63d6 Consistency please 2021-02-26 14:11:25 -08:00
Michael Shamoon
a26150ca40 Hover state for close x button 2021-02-26 14:08:13 -08:00
Michael Shamoon
57c9066f81 Closing should only navigate if closing current document 2021-02-26 14:08:04 -08:00
jonaswinkler
fe3c3b8946 Merge branch 'dev' into fix/issue-603 2021-02-26 22:25:33 +01:00
Jonas Winkler
76686c22fc Merge pull request #648 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_nl_NL
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'nl_NL'
2021-02-26 22:24:23 +01:00
Jonas Winkler
bba4057616 Merge pull request #647 from jonaswinkler/translations_src-ui-messages-xlf--dev_nl_NL
Translate '/src-ui/messages.xlf' in 'nl_NL'
2021-02-26 22:24:11 +01:00
transifex-integration[bot]
10a1f34164 Apply translations in nl_NL
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'nl_NL' language.
2021-02-26 21:07:13 +00:00
transifex-integration[bot]
4516a5def5 Translate /src-ui/messages.xlf in nl_NL
translation completed for the source file '/src-ui/messages.xlf'
on the 'nl_NL' language.
2021-02-26 21:06:40 +00:00
Jonas Winkler
4ef4af452a Merge pull request #646 from C0nsultant/ansible-CI-stability
Ansible - Fix GitHub actions
2021-02-26 21:28:43 +01:00
Fabian Koller
8f1e95a0ce Fix GitHub actions
Follow-up to #630.
The check for the target git sha can does not work in the molecule step.
Instead expose the sha through an env variable in GitHub actions.
2021-02-26 19:39:44 +01:00
Jonas Winkler
824aea0c7b Merge pull request #645 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_en_GB
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'en_GB'
2021-02-26 15:42:54 +01:00
Jonas Winkler
7d54f0e336 Merge pull request #644 from jonaswinkler/translations_src-ui-messages-xlf--dev_en_GB
Translate '/src-ui/messages.xlf' in 'en_GB'
2021-02-26 15:42:42 +01:00
transifex-integration[bot]
961b47239b Apply translations in en_GB
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'en_GB' language.
2021-02-26 14:36:09 +00:00
transifex-integration[bot]
248f19a550 Translate /src-ui/messages.xlf in en_GB
translation completed for the source file '/src-ui/messages.xlf'
on the 'en_GB' language.
2021-02-26 14:36:04 +00:00
jonaswinkler
29e6529884 Merge branch 'master' into dev 2021-02-26 15:29:58 +01:00
jonaswinkler
cb4f822a19 documentation changes 2021-02-26 15:29:33 +01:00
jonaswinkler
2159fefc87 Merge branch 'master' into dev 2021-02-26 14:54:47 +01:00
jonaswinkler
d341bf14ff Merge branch 'feature-invert-thumb-option' into dev 2021-02-26 14:31:18 +01:00
Jonas Winkler
c793ac9c6c Merge pull request #638 from smaktacular/fix-dev-setup-docs
Added First-Time Step-by-Step procedure for Dev Env and CopyPaste lists of depen…
2021-02-26 14:08:43 +01:00
jonaswinkler
289589654b tests for API versioning 2021-02-26 13:21:33 +01:00
jonaswinkler
8cb9c9faf9 Merge branch 'dev' of github.com:jonaswinkler/paperless-ng into dev 2021-02-26 13:09:14 +01:00
jonaswinkler
1c0069e95e fix pycodestyle 2021-02-26 13:09:02 +01:00
Jonas Winkler
8f23642e7d Merge pull request #643 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_de
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'de'
2021-02-26 12:59:56 +01:00
Jonas Winkler
b59758379e Merge pull request #642 from jonaswinkler/translations_src-ui-messages-xlf--dev_de
Translate '/src-ui/messages.xlf' in 'de'
2021-02-26 12:59:47 +01:00
transifex-integration[bot]
d91267ee91 Apply translations in de
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'de' language.
2021-02-26 11:59:26 +00:00
transifex-integration[bot]
6196bc7b2e Translate /src-ui/messages.xlf in de
translation completed for the source file '/src-ui/messages.xlf'
on the 'de' language.
2021-02-26 11:59:16 +00:00
jonaswinkler
adfe5c123c update messages 2021-02-26 12:57:36 +01:00
jonaswinkler
573726d0b2 add Italian locale 2021-02-26 12:55:39 +01:00
Sebastian König
5cb95b6e55 Minor changes 2021-02-26 12:50:12 +01:00
Jonas Winkler
4ce79955f8 Merge pull request #640 from jonaswinkler/translations_src-ui-messages-xlf--dev_it
Translate '/src-ui/messages.xlf' in 'it'
2021-02-26 12:35:17 +01:00
Jonas Winkler
3d320b4e61 Merge pull request #641 from jonaswinkler/translations_src-locale-en-us-lc-messages-django-po--dev_it
Translate '/src/locale/en_US/LC_MESSAGES/django.po' in 'it'
2021-02-26 12:34:58 +01:00
Bolko Schreiber
420feb3a52 lowered thumb brightness in non-inverted mode 2021-02-26 12:26:23 +01:00
transifex-integration[bot]
4d425cf7b8 Apply translations in it
translation completed for the source file '/src/locale/en_US/LC_MESSAGES/django.po'
on the 'it' language.
2021-02-26 11:24:55 +00:00
transifex-integration[bot]
f716300152 Translate /src-ui/messages.xlf in it
translation completed for the source file '/src-ui/messages.xlf'
on the 'it' language.
2021-02-26 11:02:24 +00:00
jonaswinkler
fea625e443 Merge branch 'dev' into fix/issue-603 2021-02-26 11:27:53 +01:00
jonaswinkler
068fdbd3f9 added versioning headers to the API 2021-02-26 11:13:28 +01:00
Sebastian König
fd2cbc13ff Added First-Time Step-by-Step procedure and CopyPaste lists of depeendencies to the docs 2021-02-26 09:49:36 +01:00
jonaswinkler
6a70b9c4b4 Merge branch 'feature-autocolor' into dev 2021-02-25 23:46:27 +01:00
jonaswinkler
4ee7d16d3e fix #600 2021-02-25 23:23:26 +01:00
jonaswinkler
6fd25da80d API documentation 2021-02-25 23:04:37 +01:00
jonaswinkler
2fb286cd43 shadows 2021-02-25 22:49:47 +01:00
jonaswinkler
3a75b2571a increase luminance threshold for better readability 2021-02-25 22:49:38 +01:00
jonaswinkler
66fe821b04 color picker fixes, random default color 2021-02-25 22:43:45 +01:00
jonaswinkler
ba478c6cbb tests 2021-02-25 22:17:18 +01:00
jonaswinkler
7b1145c75e bugfixes 2021-02-25 22:16:31 +01:00
jonaswinkler
b45630080b Merge branch 'dev' into feature-autocolor 2021-02-25 18:54:40 +01:00
Michael Shamoon
aadcc85e73 fix forgot to remove class when nested nav-link-additional scss block 2021-02-25 07:48:48 -08:00
Michael Shamoon
548b1ea7ec Allow closing individual documents from sidebar 2021-02-25 07:43:02 -08:00
Michael Shamoon
66f7ae3773 Remove redundant openDocuments and unused subscription 2021-02-25 07:29:51 -08:00
Bolko Schreiber
6a1f5fb4cd cleanup css 2021-02-25 15:35:15 +01:00
Bolko Schreiber
a331e4b49c Set default value of DARK_MODE_THUMB_INVERTED to true 2021-02-25 14:52:55 +01:00
Bolko Schreiber
772f5cb1a8 Added option to invert thumbnails in dark mode 2021-02-25 13:57:45 +01:00
jonaswinkler
33ed2c8851 adjust frontend to use the new tag color api 2021-02-25 11:32:22 +01:00
jonaswinkler
c75e30fd28 validate hex color strings 2021-02-25 11:30:49 +01:00
jonaswinkler
7cc940a16c add text color generation based on luminance 2021-02-25 11:30:36 +01:00
jonaswinkler
d84ca511d4 versioning for the tags API 2021-02-24 23:54:19 +01:00
jonaswinkler
95fe803bf6 remove colorhash (this will be done client side) 2021-02-24 23:52:52 +01:00
jonaswinkler
87c364a104 adjust migration 2021-02-24 23:52:25 +01:00
jonaswinkler
7233695824 Merge branch 'dev' into feature-autocolor 2021-02-24 23:10:59 +01:00
Michael Shamoon
ef7775b658 Remove object tag contents 2021-02-24 13:08:39 -08:00
Michael Shamoon
a8776603c3 Fix removed setting 2021-02-24 13:08:31 -08:00
Michael Shamoon
ee92ab1136 Support large cards 2021-02-24 13:02:26 -08:00
Michael Shamoon
83c88ca472 Unused settings 2021-02-24 12:48:58 -08:00
Michael Shamoon
6f22297158 Merge remote-tracking branch 'upstream/dev' into feature/popover-previews 2021-02-24 12:41:44 -08:00
Michael Shamoon
706b1f4622 Remove ng2-pdf-viewer and use only native viewer 2021-02-24 11:26:39 -08:00
Michael Shamoon
5306d58991 Dark mode + sizing tweaks 2021-02-07 08:19:00 -08:00
Michael Shamoon
dcb17f2f21 hide on card mouseleave 2021-02-06 14:54:36 -08:00
Michael Shamoon
37b3a30619 Better minimum size for native viewer 2021-02-06 14:30:44 -08:00
Michael Shamoon
b0fed61a01 Pre-load pdf contents 2021-02-06 14:28:26 -08:00
Michael Shamoon
4a471138b2 Dark mode popover arrow fixes 2021-02-06 14:25:53 -08:00
Michael Shamoon
41540a3a5f Document popover previews 2021-02-06 00:40:18 -08:00
jayme-github
26784a5325 Add automatic coloring of tags
Please see this as proposal on how to implement automatic/random colors
for tags while keeping the current set of hard coded colors in place (at
least in the frontend).

Bear with me as I have even less Angular knowledge than Django and just
tried to get away with as few changes as possible. :-) AIUI you want to
change to a color picking system anyways in the future, which could also
play well with this.

fixes #51
2020-12-04 10:05:47 +01:00
120 changed files with 38499 additions and 5863 deletions

View File

@@ -48,6 +48,8 @@ jobs:
molecule idempotence
molecule verify
working-directory: "${{ github.repository }}"
env:
TARGET_GITHUB_SHA: "${{ github.event.pull_request.head.sha }}"
# # https://galaxy.ansible.com/docs/contributing/importing.html
# release:
# runs-on: ubuntu-latest

View File

@@ -9,12 +9,12 @@ verify_ssl = true
name = "piwheels"
[packages]
dateparser = "~=0.7.6"
dateparser = "~=1.0.0"
django = "~=3.1.3"
django-cors-headers = "*"
django-extensions = "*"
django-filter = "~=2.4.0"
django-q = "~=1.3.4"
django-q = "==1.3.4"
djangorestframework = "~=3.12.2"
filelock = "*"
fuzzywuzzy = {extras = ["speedup"], version = "*"}
@@ -53,7 +53,7 @@ concurrent-log-handler = "*"
# uvloop 0.15+ incompatible with python 3.6
uvloop = "~=0.14.0"
# TODO: keep an eye on piwheel builds and update this once available (https://www.piwheels.org/project/cryptography/)
cryptography = "~=3.3.2"
cryptography = "~=3.4"
"pdfminer.six" = "*"
[dev-packages]

123
Pipfile.lock generated
View File

@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "71959eb287fc97969263be5e3a1b1f4f369b7a5ace85bd1947a25b9b92e17e8a"
"sha256": "49f8a0718a7982bc4ca7e1315c17849523b0d29c38f13cff88f8f883e0e9943a"
},
"pipfile-spec": 6,
"requires": {},
@@ -28,11 +28,11 @@
},
"arrow": {
"hashes": [
"sha256:e098abbd9af3665aea81bdd6c869e93af4feb078e98468dd351c383af187aac5",
"sha256:ff08d10cda1d36c68657d6ad20d74fbea493d980f8b2d45344e00d6ed2bf6ed4"
"sha256:7909d9fd30d32fa8fd173fdeb3f7125aaf6dedd1a837276fe1d8cea2c0e86d76",
"sha256:b1e106a0ab754e540f4aeb08747900830b688adef02d81240e65afc0e781a870"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==0.17.0"
"markers": "python_version >= '3.6'",
"version": "==1.0.1"
},
"asgiref": {
"hashes": [
@@ -60,11 +60,11 @@
},
"autobahn": {
"hashes": [
"sha256:41a3a3f89cde48643baf4e105d9491c566295f9abee951379e59121784044b8b",
"sha256:7e6b1bf95196b733978bab2d54a7ab8899c16ce11be369dc58422c07b7eea726"
"sha256:884f79c50fdc55ade2c315946a9caa145e8b10075eee9d2c2594ea5e8f5226aa",
"sha256:bf7a9d302a34d0f719d43c57f65ca1f2f5c982dd6ea0c11e1e190ef6f43710fe"
],
"markers": "python_version >= '3.6'",
"version": "==21.2.1"
"markers": "python_version >= '3.7'",
"version": "==21.2.2"
},
"automat": {
"hashes": [
@@ -76,10 +76,10 @@
},
"blessed": {
"hashes": [
"sha256:0a74a8d3f0366db600d061273df77d44f0db07daade7bb7a4d49c8bc22ed9f74",
"sha256:580429e7e0c6f6a42ea81b0ae5a4993b6205c6ccbb635d034b4277af8175753e"
"sha256:1312879f971330a1b7f2c6341f2ae7e2cbac244bfc9d0ecfbbecd4b0293bc755",
"sha256:5b5e2f0563d5a668c282f3f5946f7b1abb70c85829461900e607e74d7725106e"
],
"version": "==1.17.12"
"version": "==1.18.0"
},
"certifi": {
"hashes": [
@@ -190,24 +190,22 @@
},
"cryptography": {
"hashes": [
"sha256:0d7b69674b738068fa6ffade5c962ecd14969690585aaca0a1b1fc9058938a72",
"sha256:1bd0ccb0a1ed775cd7e2144fe46df9dc03eefd722bbcf587b3e0616ea4a81eff",
"sha256:3c284fc1e504e88e51c428db9c9274f2da9f73fdf5d7e13a36b8ecb039af6e6c",
"sha256:49570438e60f19243e7e0d504527dd5fe9b4b967b5a1ff21cc12b57602dd85d3",
"sha256:541dd758ad49b45920dda3b5b48c968f8b2533d8981bcdb43002798d8f7a89ed",
"sha256:5a60d3780149e13b7a6ff7ad6526b38846354d11a15e21068e57073e29e19bed",
"sha256:7951a966613c4211b6612b0352f5bf29989955ee592c4a885d8c7d0f830d0433",
"sha256:922f9602d67c15ade470c11d616f2b2364950602e370c76f0c94c94ae672742e",
"sha256:a0f0b96c572fc9f25c3f4ddbf4688b9b38c69836713fb255f4a2715d93cbaf44",
"sha256:a777c096a49d80f9d2979695b835b0f9c9edab73b59e4ceb51f19724dda887ed",
"sha256:a9a4ac9648d39ce71c2f63fe7dc6db144b9fa567ddfc48b9fde1b54483d26042",
"sha256:aa4969f24d536ae2268c902b2c3d62ab464b5a66bcb247630d208a79a8098e9b",
"sha256:c7390f9b2119b2b43160abb34f63277a638504ef8df99f11cb52c1fda66a2e6f",
"sha256:ddd06e71c449a4fe10d0c60846280ee35d69ce49e3e413ce46d5f129e1468083",
"sha256:e18e6ab84dfb0ab997faf8cca25a86ff15dfea4027b986322026cc99e0a892da"
"sha256:066bc53f052dfeda2f2d7c195cf16fb3e5ff13e1b6b7415b468514b40b381a5b",
"sha256:0923ba600d00718d63a3976f23cab19aef10c1765038945628cd9be047ad0336",
"sha256:2d32223e5b0ee02943f32b19245b61a62db83a882f0e76cc564e1cec60d48f87",
"sha256:4169a27b818de4a1860720108b55a2801f32b6ae79e7f99c00d79f2a2822eeb7",
"sha256:57ad77d32917bc55299b16d3b996ffa42a1c73c6cfa829b14043c561288d2799",
"sha256:5ecf2bcb34d17415e89b546dbb44e73080f747e504273e4d4987630493cded1b",
"sha256:600cf9bfe75e96d965509a4c0b2b183f74a4fa6f5331dcb40fb7b77b7c2484df",
"sha256:66b57a9ca4b3221d51b237094b0303843b914b7d5afd4349970bb26518e350b0",
"sha256:926ae3dfd160050158b9ca25d419fb7ee658974564b01aa10c059a75dffab7e8",
"sha256:93cfe5b7ff006de13e1e89830810ecbd014791b042cbe5eec253be11ac2b28f3",
"sha256:9e98b452132963678e3ac6c73f7010fe53adf72209a32854d55690acac3f6724",
"sha256:df186fcbf86dc1ce56305becb8434e4b6b7504bc724b71ad7a3239e0c9d14ef2",
"sha256:fec7fb46b10da10d9e1d078d1ff8ed9e05ae14f431fdbd11145edd0550b9a964"
],
"index": "pypi",
"version": "==3.3.2"
"version": "==3.4.6"
},
"daphne": {
"hashes": [
@@ -219,11 +217,11 @@
},
"dateparser": {
"hashes": [
"sha256:7552c994f893b5cb8fcf103b4cd2ff7f57aab9bfd2619fdf0cf571c0740fd90b",
"sha256:e875efd8c57c85c2d02b238239878db59ff1971f5a823457fcc69e493bf6ebfa"
"sha256:159cc4e01a593706a15cd4e269a0b3345edf3aef8bf9278a57dac8adf5bf1e4a",
"sha256:17202df32c7a36e773136ff353aa3767e987f8b3e27374c39fd21a30a803d6f8"
],
"index": "pypi",
"version": "==0.7.6"
"version": "==1.0.0"
},
"django": {
"hashes": [
@@ -415,11 +413,11 @@
},
"imap-tools": {
"hashes": [
"sha256:0eaa9b990fae336601dd44f353fac2d35ea25ca3b1b682a83700511635fc30ae",
"sha256:1c809e286d439e41fbe796c522ad4e565fd47a4260253343fa1b1045b6bfe8b1"
"sha256:44641716f0c5c07df78c5713405675fac50220d4f8e2906c9ed4aabd9c356fa8",
"sha256:bab9a6edf848a58bdd3959ba55e0eb75039ff188a3779371d0b8db674a4945e8"
],
"index": "pypi",
"version": "==0.37.0"
"version": "==0.38.1"
},
"img2pdf": {
"hashes": [
@@ -591,11 +589,11 @@
},
"ocrmypdf": {
"hashes": [
"sha256:0f624456a50be0b0bc8c0b59704d159f637616c093a1cabe8bb383706561bcf7",
"sha256:b829ad640a6160423162012e094ee2f7cd074ec99efadd7f7486954ec9182985"
"sha256:2fca4046e3a33e5902dd89c3003a3f31c7d584dc43f14c7c97f57fce20d2e469",
"sha256:5c386fcf2c0f2635533c2bad0edcd2d455f667a134d180dc61cbb3d4d5f0c8e2"
],
"index": "pypi",
"version": "==11.6.2"
"version": "==11.7.0"
},
"pathvalidate": {
"hashes": [
@@ -784,14 +782,6 @@
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.20"
},
"pyhamcrest": {
"hashes": [
"sha256:412e00137858f04bde0729913874a48485665f2d36fe9ee449f26be864af9316",
"sha256:7ead136e03655af85069b6f47b23eb7c3e5c221aa9f022a4fbb499f5b7308f29"
],
"markers": "python_version >= '3.5'",
"version": "==2.0.2"
},
"pyopenssl": {
"hashes": [
"sha256:4c231c759543ba02560fcd2480c48dcec4dae34c9da7d3747c508227e0624b51",
@@ -1097,45 +1087,22 @@
},
"tqdm": {
"hashes": [
"sha256:65185676e9fdf20d154cffd1c5de8e39ef9696ff7e59fe0156b1b08e468736af",
"sha256:70657337ec104eb4f3fb229285358f23f045433f6aea26846cdd55f0fd68945c"
"sha256:2c44efa73b8914dba7807aefd09653ac63c22b5b4ea34f7a80973f418f1a3089",
"sha256:c23ac707e8e8aabb825e4d91f8e17247f9cc14b0d64dd9e97be0781e9e525bba"
],
"index": "pypi",
"version": "==4.57.0"
"version": "==4.58.0"
},
"twisted": {
"extras": [
"tls"
],
"hashes": [
"sha256:0150dae5adc962d15e00054cc6926f1e64763fb8dd26e1632593ac06e592104b",
"sha256:040eb6641125d2a9a09cf198ec7b83dd8858c6f51f6770325ed9959c00f5098f",
"sha256:147780b8caf21ba2aef3688628eaf13d7e7fe02a86747cd54bfaf2140538f042",
"sha256:158ddb80719a4813d292293ac44ba41d8b56555ed009d90994a278237ee63d2c",
"sha256:15e52271f08f62e2230ff093e0278aa01c9dac057c4557cadadd2429eed86a3e",
"sha256:2182000d6ffc05d269e6c03bfcec8b57e20259ca1086180edaedec3f1e689292",
"sha256:25ffcf37944bdad4a99981bc74006d735a678d2b5c193781254fbbb6d69e3b22",
"sha256:3281d9ce889f7b21bdb73658e887141aa45a102baf3b2320eafcfba954fcefec",
"sha256:356e8d8dd3590e790e3dba4db139eb8a17aca64b46629c622e1b1597a4a92478",
"sha256:70952c56e4965b9f53b180daecf20a9595cf22b8d0935cd3bd664c90273c3ab2",
"sha256:7408c6635ee1b96587289283ebe90ee15dbf9614b05857b446055116bc822d29",
"sha256:7c547fd0215db9da8a1bc23182b309e84a232364cc26d829e9ee196ce840b114",
"sha256:894f6f3cfa57a15ea0d0714e4283913a5f2511dbd18653dd148eba53b3919797",
"sha256:94ac3d55a58c90e2075c5fe1853f2aa3892b73e3bf56395f743aefde8605eeaa",
"sha256:a58e61a2a01e5bcbe3b575c0099a2bcb8d70a75b1a087338e0c48dd6e01a5f15",
"sha256:c09c47ff9750a8e3aa60ad169c4b95006d455a29b80ad0901f031a103b2991cd",
"sha256:ca3a0b8c9110800e576d89b5337373e52018b41069bc879f12fa42b7eb2d0274",
"sha256:cd1dc5c85b58494138a3917752b54bb1daa0045d234b7c132c37a61d5483ebad",
"sha256:cdbc4c7f0cd7a2218b575844e970f05a1be1861c607b0e048c9bceca0c4d42f7",
"sha256:d267125cc0f1e8a0eed6319ba4ac7477da9b78a535601c49ecd20c875576433a",
"sha256:d72c55b5d56e176563b91d11952d13b01af8725c623e498db5507b6614fc1e10",
"sha256:d95803193561a243cb0401b0567c6b7987d3f2a67046770e1dccd1c9e49a9780",
"sha256:e92703bed0cc21d6cb5c61d66922b3b1564015ca8a51325bd164a5e33798d504",
"sha256:f058bd0168271de4dcdc39845b52dd0a4a2fecf5f1246335f13f5e96eaebb467",
"sha256:f3c19e5bd42bbe4bf345704ad7c326c74d3fd7a1b3844987853bef180be638d4"
"sha256:77544a8945cf69b98d2946689bbe0c75de7d145cdf11f391dd487eae8fc95a12",
"sha256:aab38085ea6cda5b378b519a0ec99986874921ee8881318626b0a3414bb2631e"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==20.3.0"
"markers": "python_full_version >= '3.5.4'",
"version": "==21.2.0"
},
"txaio": {
"hashes": [
@@ -1490,11 +1457,11 @@
},
"faker": {
"hashes": [
"sha256:31a58ec5a8f4672f24da3b5ddea02c82a712de1de3179b432948e5c34d787aca",
"sha256:aadfe0efe11ecbbbc5b3b0b0fab050c2acbd2d8e5201769546d43d236bfff663"
"sha256:90b69e9e05d622edb2fa5ebfda7bef41c88675cace85e72689fde5b8723d00a3",
"sha256:da395fe545f40d4366b82b1a02448847a4586bd2b28af393b3edbd1e45d1e0fc"
],
"markers": "python_version >= '3.6'",
"version": "==6.4.1"
"version": "==6.5.0"
},
"filelock": {
"hashes": [

View File

@@ -1,5 +1,6 @@
[![ci](https://github.com/jonaswinkler/paperless-ng/workflows/ci/badge.svg)](https://github.com/jonaswinkler/paperless-ng/actions)
![Ansible Role](https://github.com/jonaswinkler/paperless-ng/workflows/Ansible%20Role/badge.svg)
[![Crowdin](https://badges.crowdin.net/paperless-ng/localized.svg)](https://crowdin.com/project/paperless-ng)
[![Documentation Status](https://readthedocs.org/projects/paperless-ng/badge/?version=latest)](https://paperless-ng.readthedocs.io/en/latest/?badge=latest)
[![Gitter](https://badges.gitter.im/paperless-ng/community.svg)](https://gitter.im/paperless-ng/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Docker Hub Pulls](https://img.shields.io/docker/pulls/jonaswinkler/paperless-ng.svg)](https://hub.docker.com/r/jonaswinkler/paperless-ng)
@@ -77,9 +78,9 @@ The documentation for Paperless-ng is available on [ReadTheDocs](https://paperle
# Translation
Paperless is currently available in English, German, Dutch, French, and Portuguese.
Paperless is currently available in English, German, Dutch, French, Portuguese, Italian, and Romanian.
There's an active translation project at transifex! If you want to help out by translating paperless into your language, please head over to https://github.com/jonaswinkler/paperless-ng/issues/212 for details.
There's an active translation project at crowdin! If you want to help out by translating paperless into your language, please head over to https://github.com/jonaswinkler/paperless-ng/issues/212 for details.
# Feature Requests
@@ -104,9 +105,13 @@ Paperless has been around a while now, and people are starting to build stuff on
These projects also exist, but their status and compatibility with paperless-ng is unknown.
* [Paperless Desktop](https://github.com/thomasbrueggemann/paperless-desktop): A desktop UI for your Paperless installation. Runs on Mac, Linux, and Windows.
* [paperless-cli](https://github.com/stgarf/paperless-cli): A golang command line binary to interact with a Paperless instance.
This project also exists, but needs updates to be compatile with paperless-ng.
* [Paperless Desktop](https://github.com/thomasbrueggemann/paperless-desktop): A desktop UI for your Paperless installation. Runs on Mac, Linux, and Windows.
Known issues on Mac: (Could not load reminders and documents)
# 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.

View File

@@ -2,15 +2,9 @@
- name: update previous release to newest release
hosts: all
tasks:
- name: install git dependency
apt:
pkg: git
- name: obtain latest git hash in current tree
command: git rev-parse HEAD
register: git_hash
- name: set current github commit as version when available
set_fact:
paperlessng_version: "{{ git_hash.stdout }}"
paperlessng_version: "{{ lookup('env', 'TARGET_GITHUB_SHA') | default('master', True) }}"
- name: update to newest paperless-ng release
include_role:
name: ansible

View File

@@ -1,3 +1,4 @@
commit_message: '[ci skip]'
files:
- source: /src/locale/en_US/LC_MESSAGES/django.po
translation: /src/locale/%locale_with_underscore%/LC_MESSAGES/django.po

View File

@@ -184,17 +184,17 @@ Downgrades are possible. However, some updates also contain database migrations
In order to move back from a version that applied database migrations, you'll have to revert the database migration *before* downgrading,
and then downgrade paperless.
This table lists the most recent database migrations for each versions:
This table lists the compatible versions for each database migration number.
+---------+-------------------------+
| Version | Latest migration number |
+---------+-------------------------+
| 1.0.0 | 1011 |
+---------+-------------------------+
| 1.1.0 | 1011 |
+---------+-------------------------+
| 1.1.1 | 1012 |
+---------+-------------------------+
+------------------+-----------------+
| Migration number | Version range |
+------------------+-----------------+
| 1011 | 1.0.0 |
+------------------+-----------------+
| 1012 | 1.1.0 - 1.2.1 |
+------------------+-----------------+
| 1014 | 1.3.0 - current |
+------------------+-----------------+
Execute the following management command to migrate your database:

View File

@@ -10,14 +10,13 @@ easier.
Matching tags, correspondents and document types
################################################
After the consumer has tried to figure out what it could from the file name,
it starts looking at the content of the document itself. It will compare the
matching algorithms defined by every tag and correspondent already set in your
database to see if they apply to the text in that document. In other words,
if you defined a tag called ``Home Utility`` that had a ``match`` property of
``bc hydro`` and a ``matching_algorithm`` of ``literal``, 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.
Paperless will compare the matching algorithms defined by every tag and
correspondent already set in your database to see if they apply to the text in
a document. In other words, if you defined a tag called ``Home Utility``
that had a ``match`` property of ``bc hydro`` and a ``matching_algorithm`` of
``literal``, 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.
The matching logic is quite powerful, and supports searching the text of your
document with different algorithms, and as such, some experimentation may be

View File

@@ -284,3 +284,53 @@ The endpoint supports the following optional form fields:
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.
.. _api-versioning:
API Versioning
##############
The REST API is versioned since Paperless-ng 1.3.0.
* Versioning ensures that changes to the API don't break older clients.
* Clients specify the specific version of the API they wish to use with every request and Paperless will handle the request using the specified API version.
* Even if the underlying data model changes, older API versions will always serve compatible data.
* If no version is specified, Paperless will serve version 1 to ensure compatibility with older clients that do not request a specific API version.
API versions are specified by submitting an additional HTTP ``Accept`` header with every request:
.. code::
Accept: application/json; version=6
If an invalid version is specified, Paperless 1.3.0 will respond with "406 Not Acceptable" and an error message in the body.
Earlier versions of Paperless will serve API version 1 regardless of whether a version is specified via the ``Accept`` header.
If a client wishes to verify whether it is compatible with any given server, the following procedure should be performed:
1. Perform an *authenticated* request against any API endpoint. If the server is on version 1.3.0 or newer, the server will
add two custom headers to the response:
.. code::
X-Api-Version: 2
X-Version: 1.3.0
2. Determine whether the client is compatible with this server based on the presence/absence of these headers and their values if present.
API Changelog
=============
Version 1
---------
Initial API version.
Version 2
---------
* Added field ``Tag.color``. This read/write string field contains a hex color such as ``#a6cee3``.
* Added read-only field ``Tag.text_color``. This field contains the text color to use for a specific tag, which is either black or white depending on the brightness of ``Tag.color``.
* Removed field ``Tag.colour``.

View File

@@ -5,6 +5,72 @@
Changelog
*********
paperless-ng 1.3.2
##################
* Added translation into Portuguese.
* Changes
* The exporter now exports user accounts, mail accounts, mail rules and saved views as well.
* Fixes
* Minor layout issues with document cards and the log viewer.
* Fixed an issue with any/all/exact matching when characters used in regular expressions were used for the match.
paperless-ng 1.3.1
##################
* Added translation into Spanish and Russian.
* Other changes
* ISO-8601 date format will now always show years with 4 digits.
* Added the ability to search for a document with a specific ASN.
* The document cards now display ASN, types and dates in a more organized way.
* Added document previews when hovering over the preview button.
* Fixes
* The startup check for write permissions now works properly on NFS shares.
* Fixed an issue with the search results score indicator.
* Paperless was unable to generate thumbnails for encrypted PDF files and failed. Paperless will now generate a default thumbnail for these files.
* Fixed ``AUTO_LOGIN_USERNAME``: Unable to perform POST/PUT/DELETE requests and unable to receive WebSocket messages.
paperless-ng 1.3.0
##################
This release contains new database migrations.
* Changes
* The REST API is versioned from this point onwards. This will allow me to make changes without breaking existing clients. See the documentation about :ref:`api-versioning` for details.
* Added a color picker for tag colors.
* Added the ability to use the filter for searching the document content as well.
* Added translations into Italian and Romanian. Thank you!
* Close individual documents from the sidebar. Thanks to `Michael Shamoon`_.
* `BolkoSchreiber <https://github.com/BolkoSchreiber>`_ added an option to disable/enable thumbnail inversion in dark mode.
* `Simon Taddiken <https://github.com/skuzzle>`_ added the ability to customize the header used for remote user authentication with SSO applications.
* Bug fixes
* Fixed an issue with the auto matching algorithm when more than 256 tags were used.
paperless-ng 1.2.1
##################

View File

@@ -191,8 +191,28 @@ PAPERLESS_ENABLE_HTTP_REMOTE_USER=<bool>
Allows authentication via HTTP_REMOTE_USER which is used by some SSO
applications.
Defaults to `false` which disables this feature.
.. warning::
This will allow authentication by simply adding a ``Remote-User: <username>`` header
to a request. Use with care! You especially *must* ensure that any such header is not
passed from your proxy server to paperless.
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>`.
Defaults to `false` which disables this feature.
PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME=<str>
If `PAPERLESS_ENABLE_HTTP_REMOTE_USER` is enabled, this property allows to
customize the name of the HTTP header from which the authenticated username
is extracted. Values are in terms of
[HttpRequest.META](https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.HttpRequest.META).
Thus, the configured value must start with `HTTP_` followed by the
normalized actual header name.
Defaults to `HTTP_REMOTE_USER`.
.. _configuration-ocr:
OCR settings

View File

@@ -5,29 +5,82 @@ Paperless development
This section describes the steps you need to take to start development on paperless-ng.
1. Check out the source from github. The repository is organized in the following way:
Check out the source from github. The repository is organized in the following way:
* ``master`` always represents the latest release and will only see changes
when a new release is made.
* ``dev`` contains the code that will be in the next release.
* ``feature-X`` contain bigger changes that will be in some release, but not
necessarily the next one.
Apart from that, the folder structure is as follows:
* ``master`` always represents the latest release and will only see changes
when a new release is made.
* ``dev`` contains the code that will be in the next release.
* ``feature-X`` contain bigger changes that will be in some release, but not
necessarily the next one.
* ``docs/`` - Documentation.
* ``src-ui/`` - Code of the front end.
* ``src/`` - Code of the back end.
* ``scripts/`` - Various scripts that help with different parts of development.
* ``docker/`` - Files required to build the docker image.
When making functional changes to paperless, *always* make your changes on the ``dev`` branch.
2. Install some dependencies.
Apart from that, the folder structure is as follows:
* Python 3.6.
* All dependencies listed in the :ref:`Bare metal route <setup-bare_metal>`
* redis. You can either install redis or use the included scripts/start-services.sh
to use docker to fire up a redis instance (and some other services such as tika,
gotenberg and a postgresql server).
* ``docs/`` - Documentation.
* ``src-ui/`` - Code of the front end.
* ``src/`` - Code of the back end.
* ``scripts/`` - Various scripts that help with different parts of development.
* ``docker/`` - Files required to build the docker image.
Initial setup and first start
=============================
After you forked and cloned the code from github you need to perform a first-time setup.
To do the setup you need to perform the steps from the following chapters in a certain order:
1. Install prerequisites + pipenv as mentioned in :ref:`Bare metal route <setup-bare_metal>`
2. Copy ``paperless.conf.example`` to ``paperless.conf`` and enable debug mode.
3. Install the Angular CLI interface:
.. code:: shell-session
$ npm install -g @angular/cli
4. Create ``consume`` and ``media`` folders in the cloned root folder.
.. code:: shell-session
mkdir -p consume media
5. You can now either ...
* install redis or
* use the included scripts/start-services.sh to use docker to fire up a redis instance (and some other services such as tika, gotenberg and a postgresql server) or
* spin up a bare redis container
.. code:: shell-session
docker run -d -p 6379:6379 -restart unless-stopped redis:latest
6. Install the python dependencies by performing in the src/ directory.
.. code:: shell-session
pipenv install --dev
7. 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 root folder:
.. code:: shell-session
compile-frontend.sh
8. Apply migrations and create a superuser for your dev instance:
.. code:: shell-session
python3 manage.py migrate
python3 manage.py createsuperuser
9. 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.
.. code:: shell-session
python3 manage.py runserver & python3 manage.py document_consumer & python3 manage.py qcluster
10. Login with the superuser credentials provided in step 8 at ``http://localhost:8000`` to create a session that enables you to use the backend.
Backend development environment is now ready, to start Frontend development go to ``/src-ui`` and run ``ng serve``. From there you can use ``http://localhost:4200`` for a preview.
Back end development
====================
@@ -35,21 +88,18 @@ Back end development
The backend is a django application. I use PyCharm for development, but you can use whatever
you want.
Install the python dependencies by performing ``pipenv install --dev`` in the src/ directory.
This will also create a virtual environment, which you can enter with ``pipenv shell`` or
execute one-shot commands in with ``pipenv run``.
Copy ``paperless.conf.example`` to ``paperless.conf`` and enable debug mode.
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
* python3 manage.py qcluster
* python3 manage.py consumer
* python3 manage.py document_consumer
Depending on which part of paperless you're developing for, you need to have some or all of
them running.
To start them all:
.. code:: shell-session
python3 manage.py runserver & python3 manage.py document_consumer & python3 manage.py qcluster
Testing and code style:
@@ -62,7 +112,7 @@ Testing and code style:
The line length rule E501 is generally useful for getting multiple source files
next to each other on the screen. However, in some cases, its just not possible
to make some lines fit, especially complicated IF cases. Append `` # NOQA: E501``
to make some lines fit, especially complicated IF cases. Append ``# NOQA: E501``
to disable this check for certain lines.
Front end development
@@ -109,6 +159,92 @@ This will build the front end and put it in a location from which the Django ser
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 these parts have to be translated separately.
Front end localization
----------------------
* The Angular 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 translated strings need to be placed in the "src-ui/src/locale/" folder.
* In order to extract added or changed strings from the source files, call ``ng xi18n --ivy``.
Adding new languages requires adding the translated files in the "src-ui/src/locale/" folder and adjusting a couple files.
1. Adjust "src-ui/angular.json":
.. code:: json
"i18n": {
"sourceLocale": "en-US",
"locales": {
"de": "src/locale/messages.de.xlf",
"nl-NL": "src/locale/messages.nl_NL.xlf",
"fr": "src/locale/messages.fr.xlf",
"en-GB": "src/locale/messages.en_GB.xlf",
"pt-BR": "src/locale/messages.pt_BR.xlf",
"language-code": "language-file"
}
}
2. Add the language to the available options in "src-ui/src/app/services/settings.service.ts":
.. code:: typescript
getLanguageOptions(): LanguageOption[] {
return [
{code: "en-us", name: $localize`English (US)`, englishName: "English (US)", dateInputFormat: "mm/dd/yyyy"},
{code: "en-gb", name: $localize`English (GB)`, englishName: "English (GB)", dateInputFormat: "dd/mm/yyyy"},
{code: "de", name: $localize`German`, englishName: "German", dateInputFormat: "dd.mm.yyyy"},
{code: "nl", name: $localize`Dutch`, englishName: "Dutch", dateInputFormat: "dd-mm-yyyy"},
{code: "fr", name: $localize`French`, englishName: "French", dateInputFormat: "dd/mm/yyyy"},
{code: "pt-br", name: $localize`Portuguese (Brazil)`, englishName: "Portuguese (Brazil)", dateInputFormat: "dd/mm/yyyy"}
// Add your new language here
]
}
``dateInputFormat`` is a special string that defines the behavior of the date input fields and absolutely needs to contain "dd", "mm" and "yyyy".
3. Import and register the Angular data for this locale in "src-ui/src/app/app.module.ts":
.. code:: typescript
import localeDe from '@angular/common/locales/de';
registerLocaleData(localeDe)
Back end localization
---------------------
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 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/".
* 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.
* The message files need to be compiled for them to show up in the application. Call ``python3 manage.py compilemessages`` to do this. The generated files don't get
committed into git, since these are derived artifacts. The build pipeline takes care of executing this 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:
.. code:: python
LANGUAGES = [
("en-us", _("English (US)")),
("en-gb", _("English (GB)")),
("de", _("German")),
("nl-nl", _("Dutch")),
("fr", _("French")),
("pt-br", _("Portuguese (Brazil)")),
# Add language here.
]
Building the documentation
==========================
@@ -133,6 +269,23 @@ this is how you do it:
This will build the HTML documentation, and put the resulting files in the ``_build/html``
directory.
Building the Docker image
=========================
Building the docker image from source requires the following two steps:
1. Build the front end.
.. code:: shell-session
./compile-frontend.sh
2. Build the docker image.
.. code:: shell-session
docker build . -t <your-tag>
Extending Paperless
===================

View File

@@ -284,6 +284,12 @@ writing. Windows is not and will never be supported.
* ``libmagic-dev`` for mime type detection
* ``mime-support`` for mime type detection
Use this list for your preferred package management:
.. code::
python3 python3-pip python3-dev imagemagick fonts-liberation optipng gnupg libpq-dev libmagic-dev mime-support
These dependencies are required for OCRmyPDF, which is used for text recognition.
* ``unpaper``
@@ -297,6 +303,12 @@ writing. Windows is not and will never be supported.
* ``tesseract-ocr`` >= 4.0.0 for OCR
* ``tesseract-ocr`` language packs (``tesseract-ocr-eng``, ``tesseract-ocr-deu``, etc)
Use this list for your preferred package management:
.. code::
unpaper ghostscript icc-profiles-free qpdf liblept5 libxml2 pngquant zlib1g tesseract-ocr
On Raspberry Pi, these libraries are required as well:
* ``libatlas-base-dev``

View File

@@ -1,7 +1,5 @@
#!/bin/bash
set -e
ask() {
while true ; do
if [[ -z $3 ]] ; then
@@ -64,6 +62,19 @@ if [[ -z $(which docker-compose) ]] ; then
exit 1
fi
# Check if user has permissions to run Docker by trying to get the status of Docker (docker status).
# If this fails, the user probably does not have permissions for Docker.
docker stats --no-stream 2>/dev/null 1>&2
if [ $? -ne 0 ] ; then
echo ""
echo "WARN: It look like the current user does not have Docker permissions."
echo "WARN: Use 'sudo usermod -aG docker $USER' to assign Docker permissions to the user."
echo ""
sleep 3
fi
set -e
echo ""
echo "############################################"
echo "### Paperless-ng docker installation ###"

View File

@@ -8,13 +8,13 @@
-i https://pypi.python.org/simple
--extra-index-url https://www.piwheels.org/simple
aioredis==1.3.1
arrow==0.17.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
arrow==1.0.1; python_version >= '3.6'
asgiref==3.3.1; python_version >= '3.5'
async-timeout==3.0.1; python_full_version >= '3.5.3'
attrs==20.3.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
autobahn==21.2.1; python_version >= '3.6'
autobahn==21.2.2; python_version >= '3.7'
automat==20.2.0
blessed==1.17.12
blessed==1.18.0
certifi==2020.12.5
cffi==1.14.5
channels-redis==3.2.0
@@ -24,9 +24,9 @@ click==7.1.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2,
coloredlogs==15.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
concurrent-log-handler==0.9.19
constantly==15.1.0
cryptography==3.3.2
cryptography==3.4.6
daphne==3.0.1; python_version >= '3.6'
dateparser==0.7.6
dateparser==1.0.0
django-cors-headers==3.7.0
django-extensions==3.1.1
django-filter==2.4.0
@@ -43,7 +43,7 @@ httptools==0.1.1
humanfriendly==9.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
hyperlink==21.0.0
idna==2.10; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
imap-tools==0.37.0
imap-tools==0.38.1
img2pdf==0.4.0
incremental==17.5.0
inotify-simple==1.3.5; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
@@ -53,7 +53,7 @@ langdetect==1.0.8
lxml==4.6.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
msgpack==1.0.2
numpy==1.19.5
ocrmypdf==11.6.2
ocrmypdf==11.7.0
pathvalidate==2.3.2
pdfminer.six==20201018
pikepdf==2.5.2
@@ -64,7 +64,6 @@ psycopg2-binary==2.8.6
pyasn1-modules==0.2.8
pyasn1==0.4.8
pycparser==2.20; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
pyhamcrest==2.0.2; python_version >= '3.5'
pyopenssl==20.0.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
python-dateutil==2.8.1
python-dotenv==0.15.0
@@ -85,8 +84,8 @@ sortedcontainers==2.3.0
sqlparse==0.4.1; python_version >= '3.5'
threadpoolctl==2.1.0; python_version >= '3.5'
tika==1.24
tqdm==4.57.0
twisted[tls]==20.3.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
tqdm==4.58.0
twisted[tls]==21.2.0; python_full_version >= '3.5.4'
txaio==21.2.1; python_version >= '3.6'
tzlocal==2.1
urllib3==1.26.3; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'

View File

@@ -1,4 +1,4 @@
docker run -p 5432:5432 -v paperless_pgdata:/var/lib/postgresql/data -d postgres:13
docker run -p 5432:5432 -e POSTGRES_PASSWORD=password -v paperless_pgdata:/var/lib/postgresql/data -d postgres:13
docker run -d -p 6379:6379 redis:latest
docker run -p 3000:3000 -d thecodingmachine/gotenberg
docker run -p 9998:9998 -d apache/tika

View File

@@ -16,11 +16,16 @@
"i18n": {
"sourceLocale": "en-US",
"locales": {
"de": "src/locale/messages.de.xlf",
"de-DE": "src/locale/messages.de_DE.xlf",
"nl-NL": "src/locale/messages.nl_NL.xlf",
"fr": "src/locale/messages.fr.xlf",
"fr-FR": "src/locale/messages.fr_FR.xlf",
"en-GB": "src/locale/messages.en_GB.xlf",
"pt-BR": "src/locale/messages.pt_BR.xlf"
"pt-BR": "src/locale/messages.pt_BR.xlf",
"pt-PT": "src/locale/messages.pt_PT.xlf",
"it-IT": "src/locale/messages.it_IT.xlf",
"ro-RO": "src/locale/messages.ro_RO.xlf",
"ru-RU": "src/locale/messages.ru_RU.xlf",
"es-ES": "src/locale/messages.es_ES.xlf"
}
},
"architect": {
@@ -102,7 +107,8 @@
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "paperless-ui:build"
"browserTarget": "paperless-ui:build",
"ivy": true
}
},
"test": {

View File

@@ -419,7 +419,7 @@
<source>Do you really want to delete the tag &quot;<x id="PH" equiv-text="object.name"/>&quot;?</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/tag-list/tag-list.component.ts</context>
<context context-type="linenumber">30</context>
<context context-type="linenumber">26</context>
</context-group>
</trans-unit>
<trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
@@ -517,35 +517,35 @@
<source>Saved view &quot;<x id="PH" equiv-text="savedView.name"/>&quot; deleted.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">67</context>
<context context-type="linenumber">68</context>
</context-group>
</trans-unit>
<trans-unit id="5647210819299459618" datatype="html">
<source>Settings saved successfully.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">87</context>
<context context-type="linenumber">89</context>
</context-group>
</trans-unit>
<trans-unit id="6839066544204061364" datatype="html">
<source>Use system language</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="7729897675462249787" datatype="html">
<source>Use date format of display language</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
</trans-unit>
<trans-unit id="8488620293789898901" datatype="html">
<source>Error while storing settings on server: <x id="PH" equiv-text="JSON.stringify(error.error)"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">115</context>
<context context-type="linenumber">117</context>
</context-group>
</trans-unit>
<trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
@@ -566,14 +566,14 @@
<source>Notifications</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">115</context>
<context context-type="linenumber">116</context>
</context-group>
</trans-unit>
<trans-unit id="99dee94e92dbd9e21a008d4569f9719ed206ae37" datatype="html">
<source>Saved views</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">133</context>
<context context-type="linenumber">134</context>
</context-group>
</trans-unit>
<trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html">
@@ -681,102 +681,109 @@
<context context-type="linenumber">98</context>
</context-group>
</trans-unit>
<trans-unit id="71bad20b37410c8972c9aa0f7c62996534b84339" datatype="html">
<source>Invert thumbnails in dark mode</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">99</context>
</context-group>
</trans-unit>
<trans-unit id="3863a86cd9e69a61d143d3daf51df44203df4a82" datatype="html">
<source>Bulk editing</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">102</context>
<context context-type="linenumber">103</context>
</context-group>
</trans-unit>
<trans-unit id="c0ac61661c6c326d6e0e00c231b95cf2ac0c6586" datatype="html">
<source>Show confirmation dialogs</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">106</context>
<context context-type="linenumber">107</context>
</context-group>
</trans-unit>
<trans-unit id="291bbe56ecbe945dcf05580a57d679fa7bd1e06a" datatype="html">
<source>Deleting documents will always ask for confirmation.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">106</context>
<context context-type="linenumber">107</context>
</context-group>
</trans-unit>
<trans-unit id="8cfddc13e04f5545ac63f419ef363505d6f78c2e" datatype="html">
<source>Apply on close</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">107</context>
<context context-type="linenumber">108</context>
</context-group>
</trans-unit>
<trans-unit id="8680abbea249ebe9c2fe35556559c8e1a9eb5841" datatype="html">
<source>Document processing</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">119</context>
</context-group>
</trans-unit>
<trans-unit id="2ad4d76b36341c589d94004ad2a213fd4d6f5ca0" datatype="html">
<source>Show notifications when new documents are detected</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">122</context>
<context context-type="linenumber">123</context>
</context-group>
</trans-unit>
<trans-unit id="e775f4f7c40249d31426ae61a21616a0c9d8e84f" datatype="html">
<source>Show notifications when document processing completes successfully</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">123</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
<trans-unit id="e3844dd174d8e817ddb551fae28f14ae80ca36b6" datatype="html">
<source>Show notifications when document processing fails</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">124</context>
<context context-type="linenumber">125</context>
</context-group>
</trans-unit>
<trans-unit id="af113f7c9f7e13145c3461f61a1aedf12d57bd71" datatype="html">
<source>Suppress notifications on dashboard</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">125</context>
<context context-type="linenumber">126</context>
</context-group>
</trans-unit>
<trans-unit id="e27bd3804d2936a6897e81c2e52e294490e5e5a8" datatype="html">
<source>This will suppress all messages about document processing status on the dashboard.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">125</context>
<context context-type="linenumber">126</context>
</context-group>
</trans-unit>
<trans-unit id="8cb90334f5dfd7fc67205085f59381e2a334ccfc" datatype="html">
<source>Appears on</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">146</context>
</context-group>
</trans-unit>
<trans-unit id="6717cf1acf04728fc2b7c39f6d3297f8ff15fde5" datatype="html">
<source>Show on dashboard</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">148</context>
<context context-type="linenumber">149</context>
</context-group>
</trans-unit>
<trans-unit id="541bfc5b123b3f8867fd681eaceefb663a811973" datatype="html">
<source>Show in sidebar</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">152</context>
<context context-type="linenumber">153</context>
</context-group>
</trans-unit>
<trans-unit id="abba764a7a595d04dc8c3b26e04b3780d4fdb540" datatype="html">
<source>No saved views defined.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">162</context>
<context context-type="linenumber">163</context>
</context-group>
</trans-unit>
<trans-unit id="ef60a738a565f498b858e903e42bc5ffc3cc1299" datatype="html">
@@ -867,28 +874,28 @@
<source>Create new tag</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts</context>
<context context-type="linenumber">21</context>
<context context-type="linenumber">22</context>
</context-group>
</trans-unit>
<trans-unit id="5872175735754226507" datatype="html">
<source>Edit tag</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts</context>
<context context-type="linenumber">25</context>
<context context-type="linenumber">26</context>
</context-group>
</trans-unit>
<trans-unit id="f2a30b4e1a89a8a0db0bd147b54d6626b9a9bc42" datatype="html">
<source>Inbox tag</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html</context>
<context context-type="linenumber">21</context>
<context context-type="linenumber">13</context>
</context-group>
</trans-unit>
<trans-unit id="5e2f1a4ea12a1b8606ee3f0548d0ba64bf266077" datatype="html">
<source>Inbox tags are automatically assigned to all consumed documents.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html</context>
<context context-type="linenumber">21</context>
<context context-type="linenumber">13</context>
</context-group>
</trans-unit>
<trans-unit id="6672809941092516947" datatype="html">
@@ -919,32 +926,32 @@
<context context-type="linenumber">4</context>
</context-group>
</trans-unit>
<trans-unit id="2abff6a01d9b342a5a14b7fb90309a95ce934f8e" datatype="html">
<source> Showing documents similar to <x id="START_LINK" equiv-text="&lt;a routerLink=&quot;/documents/{{more_like}}&quot;&gt;{{more_like_doc?.original_file_name}}"/><x id="INTERPOLATION" equiv-text="{{more_like_doc?.original_file_name}}&lt;/a&gt;"/><x id="CLOSE_LINK" equiv-text="&lt;/a&gt;"/></source>
<trans-unit id="f7f2e30106223a69bcf0f8e586e6be9dc4e72226" datatype="html">
<source>Showing documents similar to <x id="START_LINK" equiv-text="&lt;a routerLink=&quot;/documents/{{more_like}}&quot;&gt;{{more_like_doc?.original_file_name}}"/><x id="INTERPOLATION" equiv-text="{{more_like_doc?.original_file_name}}&lt;/a&gt;"/><x id="CLOSE_LINK" equiv-text="&lt;/a&gt;"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/search/search.component.html</context>
<context context-type="linenumber">7</context>
<context context-type="linenumber">6</context>
</context-group>
</trans-unit>
<trans-unit id="6e0b0a1ea16f18f2fb1586c53d99d2f22e1aee2e" datatype="html">
<source>Search query: <x id="START_ITALIC_TEXT" equiv-text="&lt;i&gt;{{query}}"/><x id="INTERPOLATION" equiv-text="{{query}}&lt;/i&gt;"/><x id="CLOSE_ITALIC_TEXT" equiv-text="&lt;/i&gt;"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/search/search.component.html</context>
<context context-type="linenumber">11</context>
<context context-type="linenumber">9</context>
</context-group>
</trans-unit>
<trans-unit id="afa760e48c97d64d19c1455d18b7834a2256e23f" datatype="html">
<source>Did you mean &quot;<x id="START_LINK" equiv-text="&lt;a [routerLink]=&quot;&quot; (click)=&quot;searchCorrectedQuery()&quot;&gt;{{correctedQuery}}"/><x id="INTERPOLATION" equiv-text="{{correctedQuery}}&lt;/a&gt;"/><x id="CLOSE_LINK" equiv-text="&lt;/a&gt;"/>&quot;?</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/search/search.component.html</context>
<context context-type="linenumber">13</context>
<context context-type="linenumber">11</context>
</context-group>
</trans-unit>
<trans-unit id="fe6ced3fcc803bba5a2e6c1a067b9ce62542500e" datatype="html">
<source>{VAR_PLURAL, plural, =0 {No results} =1 {One result} other {<x id="INTERPOLATION"/> results}}</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/search/search.component.html</context>
<context context-type="linenumber">18</context>
<context context-type="linenumber">16</context>
</context-group>
</trans-unit>
<trans-unit id="41147374f427980a9f1a8cd5e3f4b1666e6f2418" datatype="html">
@@ -973,42 +980,42 @@
<source>Manage</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">107</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
<trans-unit id="408cb6073e60c5d966296a3207fc596adca75e01" datatype="html">
<source>Admin</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">149</context>
<context context-type="linenumber">154</context>
</context-group>
</trans-unit>
<trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5" datatype="html">
<source>Info</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">155</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="fcfd4675b4c90f08d18d3abede9a9a4dff4cfdc7" datatype="html">
<source>Documentation</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">162</context>
<context context-type="linenumber">167</context>
</context-group>
</trans-unit>
<trans-unit id="355a222236bc01b9a8cd3cb9ecf76891125aed69" datatype="html">
<source>GitHub</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">170</context>
<context context-type="linenumber">175</context>
</context-group>
</trans-unit>
<trans-unit id="ea3a452c5238897cabc5781308cceb2d37dcf258" datatype="html">
<source>Suggest an idea</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">176</context>
<context context-type="linenumber">181</context>
</context-group>
</trans-unit>
<trans-unit id="af665f8de8fabe306aaf27443957e69bcbbce63c" datatype="html">
@@ -1029,84 +1036,112 @@
<source>Close all</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">101</context>
<context context-type="linenumber">106</context>
</context-group>
</trans-unit>
<trans-unit id="5701618810648052610" datatype="html">
<source>Title</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">77</context>
</context-group>
</trans-unit>
<trans-unit id="3100631071441658964" datatype="html">
<source>Title &amp; content</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">78</context>
</context-group>
</trans-unit>
<trans-unit id="7517688192215738656" datatype="html">
<source>ASN</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="5195932016807797291" datatype="html">
<source>Correspondent: <x id="PH" equiv-text="this.correspondents.find(c =&gt; c.id == +rule.value)?.name"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">29</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="8170755470576301659" datatype="html">
<source>Without correspondent</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">31</context>
<context context-type="linenumber">35</context>
</context-group>
</trans-unit>
<trans-unit id="8705701325879965907" datatype="html">
<source>Type: <x id="PH" equiv-text="this.documentTypes.find(dt =&gt; dt.id == +rule.value)?.name"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">36</context>
<context context-type="linenumber">40</context>
</context-group>
</trans-unit>
<trans-unit id="4362173610367509215" datatype="html">
<source>Without document type</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">38</context>
<context context-type="linenumber">42</context>
</context-group>
</trans-unit>
<trans-unit id="8180755793012580465" datatype="html">
<source>Tag: <x id="PH" equiv-text="this.tags.find(t =&gt; t.id == +rule.value)?.name"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">42</context>
<context context-type="linenumber">46</context>
</context-group>
</trans-unit>
<trans-unit id="6494566478302448576" datatype="html">
<source>Without any tag</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">50</context>
</context-group>
</trans-unit>
<trans-unit id="6523384805359286307" datatype="html">
<source>Title: <x id="PH" equiv-text="rule.value"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">50</context>
<context context-type="linenumber">54</context>
</context-group>
</trans-unit>
<trans-unit id="1872523635812236432" datatype="html">
<source>ASN: <x id="PH" equiv-text="rule.value"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="02d184c288f567825a1fcbf83bcd3099a10853d5" datatype="html">
<source>Filter tags</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
<context context-type="linenumber">12</context>
<context context-type="linenumber">20</context>
</context-group>
</trans-unit>
<trans-unit id="4b089ca12c472cf0b46167bb5afe4b527b301bbc" datatype="html">
<source>Filter correspondents</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
<context context-type="linenumber">20</context>
<context context-type="linenumber">28</context>
</context-group>
</trans-unit>
<trans-unit id="0ad509732aaf702b7ea8c771c7809fa84bc85908" datatype="html">
<source>Filter document types</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
<context context-type="linenumber">27</context>
<context context-type="linenumber">35</context>
</context-group>
</trans-unit>
<trans-unit id="2d9d55f1b70142ff4597ba32179d16888fd9c6b2" datatype="html">
<source>Reset filters</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
<context context-type="linenumber">50</context>
<context context-type="linenumber">58</context>
</context-group>
</trans-unit>
<trans-unit id="7593728289020204896" datatype="html">
@@ -1128,28 +1163,28 @@
<source>Last 7 days</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/date-dropdown/date-dropdown.component.ts</context>
<context context-type="linenumber">24</context>
<context context-type="linenumber">34</context>
</context-group>
</trans-unit>
<trans-unit id="4463380307954693363" datatype="html">
<source>Last month</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/date-dropdown/date-dropdown.component.ts</context>
<context context-type="linenumber">25</context>
<context context-type="linenumber">35</context>
</context-group>
</trans-unit>
<trans-unit id="8697368973702409683" datatype="html">
<source>Last 3 months</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/date-dropdown/date-dropdown.component.ts</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">36</context>
</context-group>
</trans-unit>
<trans-unit id="3566342898065860218" datatype="html">
<source>Last year</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/date-dropdown/date-dropdown.component.ts</context>
<context context-type="linenumber">27</context>
<context context-type="linenumber">37</context>
</context-group>
</trans-unit>
<trans-unit id="be2add3a3d9e4e2556b8f9048a15a9c0f00bf1ad" datatype="html">
@@ -1163,7 +1198,7 @@
<source>Before</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/date-dropdown/date-dropdown.component.html</context>
<context context-type="linenumber">29</context>
<context context-type="linenumber">38</context>
</context-group>
</trans-unit>
<trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46" datatype="html">
@@ -1177,14 +1212,7 @@
<source>View</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
<context context-type="linenumber">50</context>
</context-group>
</trans-unit>
<trans-unit id="849b42384616374df49bd8b3711ec159cb10b845" datatype="html">
<source>Created: <x id="INTERPOLATION" equiv-text="{{document.created | customDate}}"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
<context context-type="linenumber">67</context>
<context context-type="linenumber">51</context>
</context-group>
</trans-unit>
<trans-unit id="cd6f3fd48957e1fea6545c2b2defc7b2435ebfa8" datatype="html">
@@ -1205,14 +1233,7 @@
<source>Score:</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
<context context-type="linenumber">62</context>
</context-group>
</trans-unit>
<trans-unit id="2840db547019ce8c76b2cdbe3a1653c5b68b06af" datatype="html">
<source>View in browser</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">40</context>
<context context-type="linenumber">66</context>
</context-group>
</trans-unit>
<trans-unit id="7985804062689412812" datatype="html">
@@ -1602,7 +1623,7 @@
<source>Invalid date.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/date/date.component.html</context>
<context context-type="linenumber">13</context>
<context context-type="linenumber">14</context>
</context-group>
</trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
@@ -1630,49 +1651,84 @@
<source>English (US)</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">90</context>
</context-group>
</trans-unit>
<trans-unit id="6987083569809053351" datatype="html">
<source>English (GB)</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">89</context>
<context context-type="linenumber">91</context>
</context-group>
</trans-unit>
<trans-unit id="1858110241312746425" datatype="html">
<source>German</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">90</context>
<context context-type="linenumber">92</context>
</context-group>
</trans-unit>
<trans-unit id="3071065188816255493" datatype="html">
<source>Dutch</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">91</context>
<context context-type="linenumber">93</context>
</context-group>
</trans-unit>
<trans-unit id="7633754075223722162" datatype="html">
<source>French</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="153799456510623899" datatype="html">
<source>Portuguese</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="9184513005098760425" datatype="html">
<source>Portuguese (Brazil)</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">96</context>
</context-group>
</trans-unit>
<trans-unit id="2935232983274991580" datatype="html">
<source>Italian</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">97</context>
</context-group>
</trans-unit>
<trans-unit id="8118856427047826368" datatype="html">
<source>Romanian</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">98</context>
</context-group>
</trans-unit>
<trans-unit id="7137419789978325708" datatype="html">
<source>Russian</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">99</context>
</context-group>
</trans-unit>
<trans-unit id="5190825892106392539" datatype="html">
<source>Spanish</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">100</context>
</context-group>
</trans-unit>
<trans-unit id="4912706592792948707" datatype="html">
<source>ISO 8601</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">106</context>
</context-group>
</trans-unit>
<trans-unit id="2119857572761283468" datatype="html">
@@ -1784,13 +1840,6 @@
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="7517688192215738656" datatype="html">
<source>ASN</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/rest/document.service.ts</context>
<context context-type="linenumber">17</context>
</context-group>
</trans-unit>
<trans-unit id="2691296884221415710" datatype="html">
<source>Correspondent</source>
<context-group purpose="location">
@@ -1798,13 +1847,6 @@
<context context-type="linenumber">18</context>
</context-group>
</trans-unit>
<trans-unit id="5701618810648052610" datatype="html">
<source>Title</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/rest/document.service.ts</context>
<context context-type="linenumber">19</context>
</context-group>
</trans-unit>
<trans-unit id="5066119607229701477" datatype="html">
<source>Document type</source>
<context-group purpose="location">
@@ -1833,97 +1875,6 @@
<context context-type="linenumber">23</context>
</context-group>
</trans-unit>
<trans-unit id="2056433880533904076" datatype="html">
<source>Light blue</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">6</context>
</context-group>
</trans-unit>
<trans-unit id="4082253113407591781" datatype="html">
<source>Blue</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">7</context>
</context-group>
</trans-unit>
<trans-unit id="1143414876575720034" datatype="html">
<source>Light green</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">8</context>
</context-group>
</trans-unit>
<trans-unit id="119581980963263815" datatype="html">
<source>Green</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">9</context>
</context-group>
</trans-unit>
<trans-unit id="3250646524116252719" datatype="html">
<source>Light red</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">10</context>
</context-group>
</trans-unit>
<trans-unit id="1628552745302385832" datatype="html">
<source>Red </source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">11</context>
</context-group>
</trans-unit>
<trans-unit id="5479028842846122610" datatype="html">
<source>Light orange</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">12</context>
</context-group>
</trans-unit>
<trans-unit id="8598918991528773310" datatype="html">
<source>Orange</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">13</context>
</context-group>
</trans-unit>
<trans-unit id="1789283185177957430" datatype="html">
<source>Light violet</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">14</context>
</context-group>
</trans-unit>
<trans-unit id="2682868487071320453" datatype="html">
<source>Violet</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">15</context>
</context-group>
</trans-unit>
<trans-unit id="1449010446077321264" datatype="html">
<source>Brown</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">16</context>
</context-group>
</trans-unit>
<trans-unit id="30300572504753589" datatype="html">
<source>Black</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">17</context>
</context-group>
</trans-unit>
<trans-unit id="461048771215121187" datatype="html">
<source>Light grey</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-tag.ts</context>
<context context-type="linenumber">18</context>
</context-group>
</trans-unit>
<trans-unit id="4561076822163447092" datatype="html">
<source>Create new item</source>
<context-group purpose="location">

View File

@@ -2035,6 +2035,11 @@
"to-fast-properties": "^2.0.0"
}
},
"@ctrl/tinycolor": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz",
"integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ=="
},
"@istanbuljs/schema": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
@@ -7895,6 +7900,11 @@
"object-visit": "^1.0.0"
}
},
"material-colors": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
"integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
},
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -8333,6 +8343,16 @@
}
}
},
"ngx-color": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/ngx-color/-/ngx-color-6.2.0.tgz",
"integrity": "sha512-n04tcMnCpOgmI24egST94YwHmnSoAxK8O1T2t3nGrTwWbvw5XBRJvImNFnoNrriBXzc4Gx4hFehH5MU8CZxp1w==",
"requires": {
"@ctrl/tinycolor": "^3.1.6",
"material-colors": "^1.2.6",
"tslib": "^2.0.0"
}
},
"ngx-cookie-service": {
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-10.1.1.tgz",

View File

@@ -26,6 +26,7 @@
"file-saver": "^2.0.5",
"ng-bootstrap": "^1.6.3",
"ng2-pdf-viewer": "^6.3.2",
"ngx-color": "^6.2.0",
"ngx-cookie-service": "^10.1.1",
"ngx-file-drop": "^10.0.0",
"ngx-infinite-scroll": "^9.1.0",

View File

@@ -63,18 +63,30 @@ import { DateComponent } from './components/common/input/date/date.component';
import { ISODateTimeAdapter } from './utils/ngb-iso-date-time-adapter';
import { LocalizedDateParserFormatter } from './utils/ngb-date-parser-formatter';
import { ApiVersionInterceptor } from './interceptors/api-version.interceptor';
import { ColorSliderModule } from 'ngx-color/slider';
import { ColorComponent } from './components/common/input/color/color.component';
import localeFr from '@angular/common/locales/fr';
import localeNl from '@angular/common/locales/nl';
import localeDe from '@angular/common/locales/de';
import localePt from '@angular/common/locales/pt';
import localeIt from '@angular/common/locales/it';
import localeEnGb from '@angular/common/locales/en-GB';
import localeRo from '@angular/common/locales/ro';
import localeRu from '@angular/common/locales/ru';
import localeEs from '@angular/common/locales/es';
registerLocaleData(localeFr)
registerLocaleData(localeNl)
registerLocaleData(localeDe)
registerLocaleData(localePt, "pt-BR")
registerLocaleData(localePt, "pt-PT")
registerLocaleData(localeIt)
registerLocaleData(localeEnGb)
registerLocaleData(localeRo)
registerLocaleData(localeRu)
registerLocaleData(localeEs)
@NgModule({
declarations: [
@@ -125,7 +137,8 @@ registerLocaleData(localeEnGb)
NumberComponent,
SafePipe,
CustomDatePipe,
DateComponent
DateComponent,
ColorComponent
],
imports: [
BrowserModule,
@@ -137,7 +150,8 @@ registerLocaleData(localeEnGb)
NgxFileDropModule,
InfiniteScrollModule,
PdfViewerModule,
NgSelectModule
NgSelectModule,
ColorSliderModule
],
providers: [
DatePipe,

View File

@@ -31,7 +31,7 @@
</button>
<div ngbDropdownMenu class="dropdown-menu-right shadow mr-2" aria-labelledby="userDropdown">
<div *ngIf="displayName" class="d-sm-none">
<p class="small mb-0 px-3" i18n>Logged in as {{displayName}}</p>
<p class="small mb-0 px-3 text-muted" i18n>Logged in as {{displayName}}</p>
<div class="dropdown-divider"></div>
</div>
<a ngbDropdownItem class="nav-link" routerLink="settings" (click)="closeMenu()">
@@ -92,6 +92,11 @@
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#file-text"/>
</svg>&nbsp;{{d.title | documentTitle}}
<span class="close bg-light" (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">

View File

@@ -62,16 +62,45 @@
flex-wrap: nowrap;
}
.nav-item .nav-link-additional {
margin-top: 0.2rem;
margin-left: 0.25rem;
padding-top: 0.5rem;
.nav-item {
position: relative;
svg {
margin-bottom: 2px;
&:hover .close {
display: block;
}
.close {
display: none;
position: absolute;
cursor: pointer;
opacity: 1;
top: 0;
padding: .25rem .3rem 0;
right: .4rem;
width: 1.8rem;
height: 100%;
svg {
opacity: 0.5;
}
&:hover svg {
opacity: 1;
}
}
.nav-link-additional {
margin-top: 0.2rem;
margin-left: 0.25rem;
padding-top: 0.5rem;
svg {
margin-bottom: 2px;
}
}
}
/*
* Navbar
*/

View File

@@ -1,7 +1,7 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { from, Observable, Subscription } from 'rxjs';
import { ActivatedRoute, Router, Params } from '@angular/router';
import { from, Observable, Subscription, BehaviorSubject } from 'rxjs';
import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators';
import { PaperlessDocument } from 'src/app/data/paperless-document';
import { OpenDocumentsService } from 'src/app/services/open-documents.service';
@@ -16,7 +16,7 @@ import { Meta } from '@angular/platform-browser';
templateUrl: './app-frame.component.html',
styleUrls: ['./app-frame.component.scss']
})
export class AppFrameComponent implements OnInit, OnDestroy {
export class AppFrameComponent implements OnInit {
constructor (
public router: Router,
@@ -26,7 +26,7 @@ export class AppFrameComponent implements OnInit, OnDestroy {
public savedViewService: SavedViewService,
private meta: Meta
) {
}
versionString = `${environment.appTitle} ${environment.version}`
@@ -39,9 +39,9 @@ export class AppFrameComponent implements OnInit, OnDestroy {
searchField = new FormControl('')
openDocuments: PaperlessDocument[] = []
openDocumentsSubscription: Subscription
get openDocuments(): PaperlessDocument[] {
return this.openDocumentsService.getOpenDocuments()
}
searchAutoComplete = (text$: Observable<string>) =>
text$.pipe(
@@ -77,12 +77,24 @@ export class AppFrameComponent implements OnInit, OnDestroy {
this.router.navigate(['search'], {queryParams: {query: this.searchField.value}})
}
closeDocument(d: PaperlessDocument) {
this.closeMenu()
this.openDocumentsService.closeDocument(d)
let route = this.activatedRoute.snapshot
while (route.firstChild) {
route = route.firstChild
}
if (route.component == DocumentDetailComponent && route.params['id'] == d.id) {
this.router.navigate([""])
}
}
closeAll() {
this.closeMenu()
this.openDocumentsService.closeAll()
// TODO: is there a better way to do this?
let route = this.activatedRoute
let route = this.activatedRoute.snapshot
while (route.firstChild) {
route = route.firstChild
}
@@ -92,13 +104,6 @@ export class AppFrameComponent implements OnInit, OnDestroy {
}
ngOnInit() {
this.openDocuments = this.openDocumentsService.getOpenDocuments()
}
ngOnDestroy() {
if (this.openDocumentsSubscription) {
this.openDocumentsSubscription.unsubscribe()
}
}
get displayName() {

View File

@@ -0,0 +1,33 @@
<div class="form-group">
<label [for]="inputId">{{title}}</label>
<div class="input-group" [class.is-invalid]="error">
<div class="input-group-prepend">
<span class="input-group-text" [style.background-color]="value">&nbsp;&nbsp;&nbsp;</span>
</div>
<ng-template #popContent>
<div style="min-width: 200px;" class="pb-3">
<color-slider [color]="value" (onChangeComplete)="colorChanged($event.color.hex)"></color-slider>
</div>
</ng-template>
<input class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [autoClose]="'outside'" [ngbPopover]="popContent" placement="bottom" popoverClass="shadow">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button" (click)="randomize()">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dice-5" viewBox="0 0 16 16">
<path d="M13 1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h10zM3 0a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V3a3 3 0 0 0-3-3H3z"/>
<path d="M5.5 4a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm8 0a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0 8a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm-8 0a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm4-4a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
</svg>
</button>
</div>
</div>
<small *ngIf="hint" class="form-text text-muted">{{hint}}</small>
<div class="invalid-feedback">
{{error}}
</div>
</div>

View File

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ColorComponent } from './color.component';
describe('ColorComponent', () => {
let component: ColorComponent;
let fixture: ComponentFixture<ColorComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ColorComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ColorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,30 @@
import { Component, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { randomColor } from 'src/app/utils/color';
import { AbstractInputComponent } from '../abstract-input';
@Component({
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ColorComponent),
multi: true
}],
selector: 'app-input-color',
templateUrl: './color.component.html',
styleUrls: ['./color.component.scss']
})
export class ColorComponent extends AbstractInputComponent<string> {
constructor() {
super()
}
randomize() {
this.colorChanged(randomColor())
}
colorChanged(value) {
this.value = value
this.onChange(value)
}
}

View File

@@ -1,2 +1,2 @@
<span *ngIf="!clickable" class="badge" [style.background]="getColour().value" [style.color]="getColour().textColor">{{tag.name}}</span>
<a [routerLink]="" [title]="linkTitle" *ngIf="clickable" class="badge" [style.background]="getColour().value" [style.color]="getColour().textColor">{{tag.name}}</a>
<span *ngIf="!clickable" class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</span>
<a [routerLink]="" [title]="linkTitle" *ngIf="clickable" class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</a>

View File

@@ -1,5 +1,5 @@
import { Component, Input, OnInit } from '@angular/core';
import { TAG_COLOURS, PaperlessTag } from 'src/app/data/paperless-tag';
import { PaperlessTag } from 'src/app/data/paperless-tag';
@Component({
selector: 'app-tag',
@@ -22,8 +22,4 @@ export class TagComponent implements OnInit {
ngOnInit(): void {
}
getColour() {
return TAG_COLOURS.find(c => c.id == this.tag.colour)
}
}

View File

@@ -23,7 +23,7 @@ form {
}
}
::ng-deep .progress {
.progress {
position: absolute;
top: 0;
right: 0;

View File

@@ -1,7 +1,7 @@
<div class="card mb-3 shadow-sm" [class.card-selected]="selected" [class.document-card]="selectable">
<div class="card mb-3 shadow-sm" [class.card-selected]="selected" [class.document-card]="selectable" [class.popover-hidden]="popoverHidden" (mouseleave)="mouseLeaveCard()">
<div class="row no-gutters">
<div class="col-md-2 d-none d-lg-block doc-img-background rounded-left" [class.doc-img-background-selected]="selected" (click)="this.toggleSelected.emit($event)">
<img [src]="getThumbUrl()" class="card-img doc-img border-right rounded-left">
<img [src]="getThumbUrl()" class="card-img doc-img border-right rounded-left" [class.inverted]="getIsThumbInverted()">
<div style="top: 0; left: 0" class="position-absolute border-right border-bottom bg-light p-1" [class.document-card-check]="!selected">
<div class="custom-control custom-checkbox">
@@ -23,7 +23,6 @@
{{document.title | documentTitle}}
<app-tag [tag]="t" linkTitle="Filter by tag" i18n-linkTitle *ngFor="let t of document.tags$ | async" class="ml-1" (click)="clickTag.emit(t.id);$event.stopPropagation()" [clickable]="clickTag.observers.length"></app-tag>
</h5>
<h5 class="card-title" *ngIf="document.archive_serial_number">#{{document.archive_serial_number}}</h5>
</div>
<p class="card-text">
<app-result-highlight *ngIf="getDetailsAsHighlight()" class="result-content" [highlights]="getDetailsAsHighlight()"></app-result-highlight>
@@ -43,28 +42,51 @@
<path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
</svg>&nbsp;<span class="d-block d-md-inline" i18n>Edit</span>
</a>
<a class="btn btn-sm btn-outline-secondary" [href]="getPreviewUrl()">
<a class="btn btn-sm btn-outline-secondary" [href]="previewUrl"
[ngbPopover]="previewContent" [popoverTitle]="document.title | documentTitle"
autoClose="true" popoverClass="shadow" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview()" #popover="ngbPopover">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
</svg>&nbsp;<span class="d-block d-md-inline" i18n>View</span>
</a>
<ng-template #previewContent>
<object [data]="previewUrl | safe" class="preview" width="100%"></object>
</ng-template>
<a class="btn btn-sm btn-outline-secondary" [href]="getDownloadUrl()">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-download" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
<path fill-rule="evenodd" d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
</svg>&nbsp;<span class="d-block d-md-inline" i18n>Download</span>
</a>
</div>
<div *ngIf="searchScore" class="d-flex align-items-center ml-md-auto mt-2 mt-md-0">
<small class="text-muted" i18n>Score:</small>
<ngb-progressbar [type]="searchScoreClass" [value]="searchScore" class="search-score-bar mx-2" [max]="1"></ngb-progressbar>
<div class="list-group list-group-horizontal border-0 card-info ml-md-auto mt-2 mt-md-0">
<div *ngIf="searchScore" class="list-group-item bg-light text-dark p-1 mr-5 border-0 d-flex search-score">
<small class="text-muted" i18n>Score:</small>
<ngb-progressbar [type]="searchScoreClass" [value]="searchScore" class="search-score-bar mx-2 mt-1" [max]="1"></ngb-progressbar>
</div>
<button *ngIf="document.document_type" type="button" class="list-group-item btn btn-sm bg-light text-dark p-1 border-0 mr-2" title="Filter by document type"
(click)="clickDocumentType.emit(document.document_type);$event.stopPropagation()">
<svg class="metadata-icon mr-2 text-muted bi bi-file-earmark" viewBox="0 0 16 16" fill="currentColor">
<path d="M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z"/>
</svg>
<small>{{(document.document_type$ | async)?.name}}</small>
</button>
<div *ngIf="document.archive_serial_number" class="list-group-item mr-2 bg-light text-dark p-1 border-0">
<svg class="metadata-icon mr-2 text-muted bi bi-upc-scan" viewBox="0 0 16 16" fill="currentColor">
<path d="M1.5 1a.5.5 0 0 0-.5.5v3a.5.5 0 0 1-1 0v-3A1.5 1.5 0 0 1 1.5 0h3a.5.5 0 0 1 0 1h-3zM11 .5a.5.5 0 0 1 .5-.5h3A1.5 1.5 0 0 1 16 1.5v3a.5.5 0 0 1-1 0v-3a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 1-.5-.5zM.5 11a.5.5 0 0 1 .5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 1 0 1h-3A1.5 1.5 0 0 1 0 14.5v-3a.5.5 0 0 1 .5-.5zm15 0a.5.5 0 0 1 .5.5v3a1.5 1.5 0 0 1-1.5 1.5h-3a.5.5 0 0 1 0-1h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 1 .5-.5zM3 4.5a.5.5 0 0 1 1 0v7a.5.5 0 0 1-1 0v-7zm2 0a.5.5 0 0 1 1 0v7a.5.5 0 0 1-1 0v-7zm2 0a.5.5 0 0 1 1 0v7a.5.5 0 0 1-1 0v-7zm2 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-7zm3 0a.5.5 0 0 1 1 0v7a.5.5 0 0 1-1 0v-7z"/>
</svg>
<small>#{{document.archive_serial_number}}</small>
</div>
<div class="list-group-item bg-light text-dark p-1 border-0" ngbTooltip="Added:&nbsp;{{document.added | customDate:'shortDate'}} Created:&nbsp;{{document.created | customDate:'shortDate'}}">
<svg class="metadata-icon mr-2 text-muted bi bi-calendar-event" viewBox="0 0 16 16" fill="currentColor">
<path d="M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1z"/>
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/>
</svg>
<small>{{document.created | customDate:'mediumDate'}}</small>
</div>
</div>
<small class="text-muted" [class.ml-auto]="!searchScore" i18n>Created: {{document.created | customDate}}</small>
</div>
</div>

View File

@@ -37,3 +37,26 @@
.doc-img-background-selected {
background-color: $primaryFaded;
}
.card-info {
line-height: 1;
button {
line-height: 1;
&:hover,
&:focus {
background-color: transparent !important;
}
}
.metadata-icon {
width: 0.9rem;
height: 0.9rem;
padding: 0.05rem;
}
.search-score {
padding-top: 0.35rem !important;
}
}

View File

@@ -1,16 +1,18 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { PaperlessDocument } from 'src/app/data/paperless-document';
import { DocumentService } from 'src/app/services/rest/document.service';
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-document-card-large',
templateUrl: './document-card-large.component.html',
styleUrls: ['./document-card-large.component.scss']
styleUrls: ['./document-card-large.component.scss', '../popover-preview/popover-preview.scss']
})
export class DocumentCardLargeComponent implements OnInit {
constructor(private documentService: DocumentService, private sanitizer: DomSanitizer) { }
constructor(private documentService: DocumentService, private sanitizer: DomSanitizer, private settingsService: SettingsService) { }
@Input()
selected = false
@@ -37,9 +39,17 @@ export class DocumentCardLargeComponent implements OnInit {
@Output()
clickCorrespondent = new EventEmitter<number>()
@Output()
clickDocumentType = new EventEmitter<number>()
@Input()
searchScore: number
@ViewChild('popover') popover: NgbPopover
mouseOnPreview = false
popoverHidden = true
get searchScoreClass() {
if (this.searchScore > 0.7) {
return "success"
@@ -53,6 +63,10 @@ export class DocumentCardLargeComponent implements OnInit {
ngOnInit(): void {
}
getIsThumbInverted() {
return this.settingsService.get(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED)
}
getDetailsAsString() {
if (typeof this.details === 'string') {
return this.details.substring(0, 500)
@@ -74,7 +88,32 @@ export class DocumentCardLargeComponent implements OnInit {
return this.documentService.getDownloadUrl(this.document.id)
}
getPreviewUrl() {
get previewUrl() {
return this.documentService.getPreviewUrl(this.document.id)
}
mouseEnterPreview() {
this.mouseOnPreview = true
if (!this.popover.isOpen()) {
// we're going to open but hide to pre-load content during hover delay
this.popover.open()
this.popoverHidden = true
setTimeout(() => {
if (this.mouseOnPreview) {
// show popover
this.popoverHidden = false
} else {
this.popover.close()
}
}, 600);
}
}
mouseLeavePreview() {
this.mouseOnPreview = false
}
mouseLeaveCard() {
this.popover.close()
}
}

View File

@@ -1,7 +1,7 @@
<div class="col p-2 h-100">
<div class="card h-100 shadow-sm document-card" [class.card-selected]="selected">
<div class="card h-100 shadow-sm document-card" [class.card-selected]="selected" [class.popover-hidden]="popoverHidden" (mouseleave)="mouseLeaveCard()">
<div class="border-bottom doc-img-container" [class.doc-img-background-selected]="selected" (click)="this.toggleSelected.emit($event)">
<img class="card-img doc-img rounded-top" [src]="getThumbUrl()">
<img class="card-img doc-img rounded-top" [class.inverted]="getIsThumbInverted()" [src]="getThumbUrl()">
<div class="border-right border-bottom bg-light p-1 rounded document-card-check">
<div class="custom-control custom-checkbox">
@@ -25,24 +25,52 @@
<ng-container *ngIf="document.correspondent">
<a [routerLink]="" title="Filter by correspondent" i18n-title (click)="clickCorrespondent.emit(document.correspondent);$event.stopPropagation()" class="font-weight-bold">{{(document.correspondent$ | async)?.name}}</a>:
</ng-container>
{{document.title | documentTitle}} <span *ngIf="document.archive_serial_number">(#{{document.archive_serial_number}})</span>
{{document.title | documentTitle}}
</p>
</div>
<div class="card-footer">
<div class="d-flex justify-content-between align-items-center mx-n2">
<div class="btn-group">
<div class="card-footer pt-0 pb-2 px-2">
<div class="list-group list-group-flush border-0 pt-1 pb-2 card-info">
<button *ngIf="document.document_type" type="button" class="list-group-item list-group-item-action bg-transparent pl-0 p-1 border-0" title="Filter by document type"
(click)="clickDocumentType.emit(document.document_type);$event.stopPropagation()">
<svg class="metadata-icon mr-2 text-muted bi bi-file-earmark" viewBox="0 0 16 16" fill="currentColor">
<path d="M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z"/>
</svg>
<small>{{(document.document_type$ | async)?.name}}</small>
</button>
<div class="list-group-item bg-transparent p-0 border-0 d-flex flex-wrap-reverse justify-content-between">
<div class="pl-0 p-1" placement="top" ngbTooltip="Added:&nbsp;{{document.added | customDate:'mediumDate'}} Created:&nbsp;{{document.created | customDate:'mediumDate'}}">
<svg class="metadata-icon mr-2 text-muted bi bi-calendar-event" viewBox="0 0 16 16" fill="currentColor">
<path d="M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1z"/>
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/>
</svg>
<small>{{document.created | customDate:'mediumDate'}}</small>
</div>
<div *ngIf="document.archive_serial_number" class="pl-0 p-1">
<svg class="metadata-icon mr-2 text-muted bi bi-upc-scan" viewBox="0 0 16 16" fill="currentColor">
<path d="M1.5 1a.5.5 0 0 0-.5.5v3a.5.5 0 0 1-1 0v-3A1.5 1.5 0 0 1 1.5 0h3a.5.5 0 0 1 0 1h-3zM11 .5a.5.5 0 0 1 .5-.5h3A1.5 1.5 0 0 1 16 1.5v3a.5.5 0 0 1-1 0v-3a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 1-.5-.5zM.5 11a.5.5 0 0 1 .5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 1 0 1h-3A1.5 1.5 0 0 1 0 14.5v-3a.5.5 0 0 1 .5-.5zm15 0a.5.5 0 0 1 .5.5v3a1.5 1.5 0 0 1-1.5 1.5h-3a.5.5 0 0 1 0-1h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 1 .5-.5zM3 4.5a.5.5 0 0 1 1 0v7a.5.5 0 0 1-1 0v-7zm2 0a.5.5 0 0 1 1 0v7a.5.5 0 0 1-1 0v-7zm2 0a.5.5 0 0 1 1 0v7a.5.5 0 0 1-1 0v-7zm2 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-7zm3 0a.5.5 0 0 1 1 0v7a.5.5 0 0 1-1 0v-7z"/>
</svg>
<small>#{{document.archive_serial_number}}</small>
</div>
</div>
</div>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group w-100">
<a routerLink="/documents/{{document.id}}" class="btn btn-sm btn-outline-secondary" title="Edit" i18n-title>
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-pencil" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
</svg>
</a>
<a [href]="getPreviewUrl()" class="btn btn-sm btn-outline-secondary" title="View in browser" i18n-title>
<a [href]="previewUrl" target="_blank" class="btn btn-sm btn-outline-secondary"
[ngbPopover]="previewContent" [popoverTitle]="document.title | documentTitle"
autoClose="true" popoverClass="shadow" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview()" #popover="ngbPopover">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
</svg>
</a>
<ng-template #previewContent>
<object [data]="previewUrl | safe" class="preview" width="100%"></object>
</ng-template>
<a [href]="getDownloadUrl()" class="btn btn-sm btn-outline-secondary" title="Download" (click)="$event.stopPropagation()" i18n-title>
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-download" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
@@ -50,9 +78,7 @@
</svg>
</a>
</div>
<small class="text-muted pl-1">{{document.created | customDate:'shortDate'}}</small>
</div>
</div>
</div>
</div>

View File

@@ -1,9 +1,13 @@
@import "/src/theme";
.card-text {
font-size: 90%;
}
.doc-img {
object-fit: cover;
object-position: top left;
height: 200px;
height: 175px;
mix-blend-mode: multiply;
}
@@ -34,3 +38,32 @@
.doc-img-background-selected {
background-color: $primaryFaded;
}
.card-info {
line-height: 1;
button {
line-height: 1;
&:hover,
&:focus {
background-color: transparent !important;
color: $primary;
}
}
.metadata-icon {
width: 0.9rem;
height: 0.9rem;
padding: 0.05rem;
}
}
.card-footer .btn {
padding-top: .10rem;
}
::ng-deep .tooltip-inner {
text-align: left !important;
font-size: 90%;
}

View File

@@ -1,20 +1,22 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { map } from 'rxjs/operators';
import { PaperlessDocument } from 'src/app/data/paperless-document';
import { DocumentService } from 'src/app/services/rest/document.service';
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-document-card-small',
templateUrl: './document-card-small.component.html',
styleUrls: ['./document-card-small.component.scss']
styleUrls: ['./document-card-small.component.scss', '../popover-preview/popover-preview.scss']
})
export class DocumentCardSmallComponent implements OnInit {
constructor(private documentService: DocumentService) { }
constructor(private documentService: DocumentService, private settingsService: SettingsService) { }
@Input()
selected = false
@Output()
toggleSelected = new EventEmitter()
@@ -27,11 +29,23 @@ export class DocumentCardSmallComponent implements OnInit {
@Output()
clickCorrespondent = new EventEmitter<number>()
@Output()
clickDocumentType = new EventEmitter<number>()
moreTags: number = null
@ViewChild('popover') popover: NgbPopover
mouseOnPreview = false
popoverHidden = true
ngOnInit(): void {
}
getIsThumbInverted() {
return this.settingsService.get(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED)
}
getThumbUrl() {
return this.documentService.getThumbUrl(this.document.id)
}
@@ -40,7 +54,7 @@ export class DocumentCardSmallComponent implements OnInit {
return this.documentService.getDownloadUrl(this.document.id)
}
getPreviewUrl() {
get previewUrl() {
return this.documentService.getPreviewUrl(this.document.id)
}
@@ -57,4 +71,28 @@ export class DocumentCardSmallComponent implements OnInit {
)
}
mouseEnterPreview() {
this.mouseOnPreview = true
if (!this.popover.isOpen()) {
// we're going to open but hide to pre-load content during hover delay
this.popover.open()
this.popoverHidden = true
setTimeout(() => {
if (this.mouseOnPreview) {
// show popover
this.popoverHidden = false
} else {
this.popover.close()
}
}, 600);
}
}
mouseLeavePreview() {
this.mouseOnPreview = false
}
mouseLeaveCard() {
this.popover.close()
}
}

View File

@@ -90,7 +90,7 @@
</div>
<div *ngIf="displayMode == 'largeCards'">
<app-document-card-large [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" *ngFor="let d of list.documents; trackBy: trackByDocumentId" [document]="d" [details]="d.content" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)">
<app-document-card-large [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" *ngFor="let d of list.documents; trackBy: trackByDocumentId" [document]="d" [details]="d.content" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)" (clickDocumentType)="clickDocumentType($event)">
</app-document-card-large>
</div>
@@ -170,5 +170,5 @@
</table>
<div class="m-n2 row row-cols-paperless-cards" *ngIf="displayMode == 'smallCards'">
<app-document-card-small [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" [document]="d" *ngFor="let d of list.documents; trackBy: trackByDocumentId" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)"></app-document-card-small>
<app-document-card-small [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" [document]="d" *ngFor="let d of list.documents; trackBy: trackByDocumentId" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)" (clickDocumentType)="clickDocumentType($event)"></app-document-card-small>
</div>

View File

@@ -2,7 +2,15 @@
<div class="col mb-2 mb-xl-0">
<div class="form-inline d-flex align-items-center">
<label class="text-muted mr-2 mb-0" i18n>Filter by:</label>
<input class="form-control form-control-sm flex-fill w-auto" type="text" [(ngModel)]="titleFilter" placeholder="Title" i18n-placeholder>
<div class="input-group input-group-sm flex-fill w-auto">
<div class="input-group-prepend" ngbDropdown>
<button class="btn btn-outline-primary" ngbDropdownToggle>{{textFilterTargetName}}</button>
<div class="dropdown-menu shadow" ngbDropdownMenu>
<button *ngFor="let t of textFilterTargets" ngbDropdownItem [class.active]="textFilterTarget == t.id" (click)="changeTextFilterTarget(t.id)">{{t.name}}</button>
</div>
</div>
<input class="form-control form-control-sm" type="text" [(ngModel)]="textFilter">
</div>
</div>
</div>
<div class="w-100 d-xl-none"></div>

View File

@@ -8,10 +8,14 @@ import { DocumentTypeService } from 'src/app/services/rest/document-type.service
import { TagService } from 'src/app/services/rest/tag.service';
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
import { FilterRule } from 'src/app/data/filter-rule';
import { FILTER_ADDED_AFTER, FILTER_ADDED_BEFORE, FILTER_CORRESPONDENT, FILTER_CREATED_AFTER, FILTER_CREATED_BEFORE, FILTER_DOCUMENT_TYPE, FILTER_HAS_ANY_TAG, FILTER_HAS_TAG, FILTER_TITLE } from 'src/app/data/filter-rule-type';
import { FILTER_ADDED_AFTER, FILTER_ADDED_BEFORE, FILTER_ASN, FILTER_CORRESPONDENT, FILTER_CREATED_AFTER, FILTER_CREATED_BEFORE, FILTER_DOCUMENT_TYPE, FILTER_HAS_ANY_TAG, FILTER_HAS_TAG, FILTER_TITLE, FILTER_TITLE_CONTENT } from 'src/app/data/filter-rule-type';
import { FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component';
const TEXT_FILTER_TARGET_TITLE = "title"
const TEXT_FILTER_TARGET_TITLE_CONTENT = "title-content"
const TEXT_FILTER_TARGET_ASN = "asn"
@Component({
selector: 'app-filter-editor',
templateUrl: './filter-editor.component.html',
@@ -48,6 +52,9 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
case FILTER_TITLE:
return $localize`Title: ${rule.value}`
case FILTER_ASN:
return $localize`ASN: ${rule.value}`
}
}
@@ -64,7 +71,20 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
correspondents: PaperlessCorrespondent[] = []
documentTypes: PaperlessDocumentType[] = []
_titleFilter = ""
_textFilter = ""
textFilterTargets = [
{id: TEXT_FILTER_TARGET_TITLE, name: $localize`Title`},
{id: TEXT_FILTER_TARGET_TITLE_CONTENT, name: $localize`Title & content`},
{id: TEXT_FILTER_TARGET_ASN, name: $localize`ASN`}
]
textFilterTarget = TEXT_FILTER_TARGET_TITLE_CONTENT
get textFilterTargetName() {
return this.textFilterTargets.find(t => t.id == this.textFilterTarget)?.name
}
tagSelectionModel = new FilterableDropdownSelectionModel()
correspondentSelectionModel = new FilterableDropdownSelectionModel()
@@ -80,7 +100,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
this.documentTypeSelectionModel.clear(false)
this.tagSelectionModel.clear(false)
this.correspondentSelectionModel.clear(false)
this._titleFilter = null
this._textFilter = null
this.dateAddedBefore = null
this.dateAddedAfter = null
this.dateCreatedBefore = null
@@ -89,7 +109,16 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
value.forEach(rule => {
switch (rule.rule_type) {
case FILTER_TITLE:
this._titleFilter = rule.value
this._textFilter = rule.value
this.textFilterTarget = TEXT_FILTER_TARGET_TITLE
break
case FILTER_TITLE_CONTENT:
this._textFilter = rule.value
this.textFilterTarget = TEXT_FILTER_TARGET_TITLE_CONTENT
break
case FILTER_ASN:
this._textFilter = rule.value
this.textFilterTarget = TEXT_FILTER_TARGET_ASN
break
case FILTER_CREATED_AFTER:
this.dateCreatedAfter = rule.value
@@ -121,8 +150,14 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
get filterRules(): FilterRule[] {
let filterRules: FilterRule[] = []
if (this._titleFilter) {
filterRules.push({rule_type: FILTER_TITLE, value: this._titleFilter})
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_TITLE_CONTENT) {
filterRules.push({rule_type: FILTER_TITLE_CONTENT, value: this._textFilter})
}
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_TITLE) {
filterRules.push({rule_type: FILTER_TITLE, value: this._textFilter})
}
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_ASN) {
filterRules.push({rule_type: FILTER_ASN, value: this._textFilter})
}
if (this.tagSelectionModel.isNoneSelected()) {
filterRules.push({rule_type: FILTER_HAS_ANY_TAG, value: "false"})
@@ -165,15 +200,15 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
this.filterRulesChange.next(this.filterRules)
}
get titleFilter() {
return this._titleFilter
get textFilter() {
return this._textFilter
}
set titleFilter(value) {
this.titleFilterDebounce.next(value)
set textFilter(value) {
this.textFilterDebounce.next(value)
}
titleFilterDebounce: Subject<string>
textFilterDebounce: Subject<string>
subscription: Subscription
ngOnInit() {
@@ -181,19 +216,19 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
this.correspondentService.listAll().subscribe(result => this.correspondents = result.results)
this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results)
this.titleFilterDebounce = new Subject<string>()
this.textFilterDebounce = new Subject<string>()
this.subscription = this.titleFilterDebounce.pipe(
this.subscription = this.textFilterDebounce.pipe(
debounceTime(400),
distinctUntilChanged()
).subscribe(title => {
this._titleFilter = title
).subscribe(text => {
this._textFilter = text
this.updateRules()
})
}
ngOnDestroy() {
this.titleFilterDebounce.complete()
this.textFilterDebounce.complete()
}
resetSelected() {
@@ -223,4 +258,9 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
onDocumentTypeDropdownOpen() {
this.documentTypeSelectionModel.apply()
}
changeTextFilterTarget(target) {
this.textFilterTarget = target
this.updateRules()
}
}

View File

@@ -0,0 +1,22 @@
::ng-deep .popover {
max-width: 40rem;
.preview {
min-width: 30rem;
min-height: 18rem;
max-height: 35rem;
overflow-y: scroll;
}
.spinner-border {
position: absolute;
top: 4rem;
left: calc(50% - 0.5rem);
z-index: 0;
}
}
::ng-deep .popover-hidden .popover {
opacity: 0;
pointer-events: none;
}

View File

@@ -11,8 +11,8 @@
<div [ngbNavOutlet]="nav" class="mt-2"></div>
<div class="bg-dark p-3 mb-3 text-light text-monospace log-container">
<div class="bg-dark p-3 text-light text-monospace log-container" #logContainer>
<p
class="m-0 p-0 log-entry-{{getLogLevel(log)}}"
*ngFor="let log of logs" style="white-space: pre;">{{log}}</p>
*ngFor="let log of logs">{{log}}</p>
</div>

View File

@@ -16,9 +16,11 @@
}
.log-container {
overflow: scroll;
height: calc(100vh - 190px);
overflow-y: scroll;
height: calc(100vh - 200px);
top: 70px;
}
p {
white-space: pre-wrap;
}
}

View File

@@ -1,4 +1,4 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { Component, ElementRef, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
import { LogService } from 'src/app/services/rest/log.service';
@Component({
@@ -6,7 +6,7 @@ import { LogService } from 'src/app/services/rest/log.service';
templateUrl: './logs.component.html',
styleUrls: ['./logs.component.scss']
})
export class LogsComponent implements OnInit {
export class LogsComponent implements OnInit, AfterViewChecked {
constructor(private logService: LogService) { }
@@ -16,6 +16,8 @@ export class LogsComponent implements OnInit {
activeLog: string
@ViewChild('logContainer') logContainer: ElementRef
ngOnInit(): void {
this.logService.list().subscribe(result => {
this.logFiles = result
@@ -26,6 +28,10 @@ export class LogsComponent implements OnInit {
})
}
ngAfterViewChecked() {
this.scrollToBottom();
}
reloadLogs() {
this.logService.get(this.activeLog).subscribe(result => {
this.logs = result
@@ -48,4 +54,12 @@ export class LogsComponent implements OnInit {
}
}
scrollToBottom(): void {
this.logContainer?.nativeElement.scroll({
top: this.logContainer.nativeElement.scrollHeight,
left: 0,
behavior: 'auto'
});
}
}

View File

@@ -96,6 +96,7 @@
<div class="col">
<app-input-check i18n-title title="Use system settings" formControlName="darkModeUseSystem"></app-input-check>
<app-input-check [hidden]="settingsForm.value.darkModeUseSystem" i18n-title title="Enable dark mode" formControlName="darkModeEnabled"></app-input-check>
<app-input-check i18n-title title="Invert thumbnails in dark mode" formControlName="darkModeInvertThumbs"></app-input-check>
</div>
</div>
@@ -110,11 +111,11 @@
</ng-template>
</li>
<li [ngbNavItem]="2">
<a ngbNavLink i18n>Notifications</a>
<ng-template ngbNavContent>
<h4 i18n>Document processing</h4>
<div class="form-row form-group">

View File

@@ -21,6 +21,7 @@ export class SettingsComponent implements OnInit {
'documentListItemPerPage': new FormControl(this.settings.get(SETTINGS_KEYS.DOCUMENT_LIST_SIZE)),
'darkModeUseSystem': new FormControl(this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM)),
'darkModeEnabled': new FormControl(this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED)),
'darkModeInvertThumbs': new FormControl(this.settings.get(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED)),
'useNativePdfViewer': new FormControl(this.settings.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER)),
'savedViews': this.savedViewGroup,
'displayLanguage': new FormControl(this.settings.getLanguage()),
@@ -74,6 +75,7 @@ export class SettingsComponent implements OnInit {
this.settings.set(SETTINGS_KEYS.DOCUMENT_LIST_SIZE, this.settingsForm.value.documentListItemPerPage)
this.settings.set(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, this.settingsForm.value.darkModeUseSystem)
this.settings.set(SETTINGS_KEYS.DARK_MODE_ENABLED, (this.settingsForm.value.darkModeEnabled == true).toString())
this.settings.set(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED, (this.settingsForm.value.darkModeInvertThumbs == true).toString())
this.settings.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, this.settingsForm.value.useNativePdfViewer)
this.settings.set(SETTINGS_KEYS.DATE_LOCALE, this.settingsForm.value.dateLocale)
this.settings.set(SETTINGS_KEYS.DATE_FORMAT, this.settingsForm.value.dateFormat)

View File

@@ -8,15 +8,7 @@
<div class="modal-body">
<app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
<div class="form-group paperless-input-select">
<label for="colour" i18n>Color</label>
<ng-select name="colour" formControlName="colour" [items]="getColours()" bindValue="id" bindLabel="name" [clearable]="false">
<ng-template ng-option-tmp ng-label-tmp let-item="item">
<span class="badge" [style.background]="item.value" [style.color]="item.textColor">{{item.name}}</span>
</ng-template>
</ng-select>
</div>
<app-input-color i18n-title title="Color" formControlName="color" [error]="error?.color"></app-input-color>
<app-input-check i18n-title title="Inbox tag" formControlName="is_inbox_tag" i18n-hint hint="Inbox tags are automatically assigned to all consumed documents."></app-input-check>
<app-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></app-input-select>

View File

@@ -2,9 +2,10 @@ 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 { TAG_COLOURS, PaperlessTag } from 'src/app/data/paperless-tag';
import { PaperlessTag } from 'src/app/data/paperless-tag';
import { TagService } from 'src/app/services/rest/tag.service';
import { ToastService } from 'src/app/services/toast.service';
import { randomColor } from 'src/app/utils/color';
@Component({
selector: 'app-tag-edit-dialog',
@@ -13,7 +14,7 @@ import { ToastService } from 'src/app/services/toast.service';
})
export class TagEditDialogComponent extends EditDialogComponent<PaperlessTag> {
constructor(service: TagService, activeModal: NgbActiveModal, toastService: ToastService) {
constructor(service: TagService, activeModal: NgbActiveModal, toastService: ToastService) {
super(service, activeModal, toastService)
}
@@ -28,7 +29,7 @@ export class TagEditDialogComponent extends EditDialogComponent<PaperlessTag> {
getForm(): FormGroup {
return new FormGroup({
name: new FormControl(''),
colour: new FormControl(1),
color: new FormControl(randomColor()),
is_inbox_tag: new FormControl(false),
matching_algorithm: new FormControl(1),
match: new FormControl(""),
@@ -36,12 +37,4 @@ export class TagEditDialogComponent extends EditDialogComponent<PaperlessTag> {
})
}
getColours() {
return TAG_COLOURS
}
getColor(id: number) {
return TAG_COLOURS.find(c => c.id == id)
}
}

View File

@@ -26,8 +26,8 @@
<tbody>
<tr *ngFor="let tag of data">
<td scope="row">{{ tag.name }}</td>
<td scope="row"><span class="badge" [style.color]="getColor(tag.colour).textColor"
[style.background-color]="getColor(tag.colour).value">{{ getColor(tag.colour).name }}</span></td>
<td scope="row"><span class="badge" [style.color]="tag.text_color"
[style.background-color]="tag.color">{{tag.color}}</span></td>
<td scope="row">{{ getMatching(tag) }}</td>
<td scope="row">{{ tag.document_count }}</td>
<td scope="row">

View File

@@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { FILTER_HAS_TAG } from 'src/app/data/filter-rule-type';
import { TAG_COLOURS, PaperlessTag } from 'src/app/data/paperless-tag';
import { PaperlessTag } from 'src/app/data/paperless-tag';
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
import { TagService } from 'src/app/services/rest/tag.service';
import { ToastService } from 'src/app/services/toast.service';
@@ -22,10 +22,6 @@ export class TagListComponent extends GenericListComponent<PaperlessTag> {
super(tagService, modalService, TagEditDialogComponent, toastService)
}
getColor(id) {
return TAG_COLOURS.find(c => c.id == id)
}
getDeleteMessage(object: PaperlessTag) {
return $localize`Do you really want to delete the tag "${object.name}"?`
}

View File

@@ -3,9 +3,7 @@
<div *ngIf="errorMessage" class="alert alert-danger" i18n>Invalid search query: {{errorMessage}}</div>
<p *ngIf="more_like" i18n>
Showing documents similar to <a routerLink="/documents/{{more_like}}">{{more_like_doc?.original_file_name}}</a>
</p>
<p *ngIf="more_like" i18n>Showing documents similar to <a routerLink="/documents/{{more_like}}">{{more_like_doc?.original_file_name}}</a></p>
<p *ngIf="query">
<ng-container i18n>Search query: <i>{{query}}</i></ng-container>

View File

@@ -20,6 +20,8 @@ export const FILTER_DOES_NOT_HAVE_TAG = 17
export const FILTER_ASN_ISNULL = 18
export const FILTER_TITLE_CONTENT = 19
export const FILTER_RULE_TYPES: FilterRuleType[] = [
{id: FILTER_TITLE, filtervar: "title__icontains", datatype: "string", multi: false, default: ""},
@@ -47,7 +49,9 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
{id: FILTER_MODIFIED_BEFORE, filtervar: "modified__date__lt", datatype: "date", multi: false},
{id: FILTER_MODIFIED_AFTER, filtervar: "modified__date__gt", datatype: "date", multi: false},
{id: FILTER_ASN_ISNULL, filtervar: "archive_serial_number__isnull", datatype: "boolean", multi: false}
{id: FILTER_ASN_ISNULL, filtervar: "archive_serial_number__isnull", datatype: "boolean", multi: false},
{id: FILTER_TITLE_CONTENT, filtervar: "title_content", datatype: "string", multi: false}
]
export interface FilterRuleType {

View File

@@ -1,26 +1,10 @@
import { MatchingModel } from './matching-model';
import { ObjectWithId } from './object-with-id';
export const TAG_COLOURS = [
{id: 1, value: "#a6cee3", name: $localize`Light blue`, textColor: "#000000"},
{id: 2, value: "#1f78b4", name: $localize`Blue`, textColor: "#ffffff"},
{id: 3, value: "#b2df8a", name: $localize`Light green`, textColor: "#000000"},
{id: 4, value: "#33a02c", name: $localize`Green`, textColor: "#ffffff"},
{id: 5, value: "#fb9a99", name: $localize`Light red`, textColor: "#000000"},
{id: 6, value: "#e31a1c", name: $localize`Red `, textColor: "#ffffff"},
{id: 7, value: "#fdbf6f", name: $localize`Light orange`, textColor: "#000000"},
{id: 8, value: "#ff7f00", name: $localize`Orange`, textColor: "#000000"},
{id: 9, value: "#cab2d6", name: $localize`Light violet`, textColor: "#000000"},
{id: 10, value: "#6a3d9a", name: $localize`Violet`, textColor: "#ffffff"},
{id: 11, value: "#b15928", name: $localize`Brown`, textColor: "#ffffff"},
{id: 12, value: "#000000", name: $localize`Black`, textColor: "#ffffff"},
{id: 13, value: "#cccccc", name: $localize`Light grey`, textColor: "#000000"}
]
import { MatchingModel } from "./matching-model";
export interface PaperlessTag extends MatchingModel {
colour?: number
color?: string
text_color?: string
is_inbox_tag?: boolean

View File

@@ -4,8 +4,8 @@ import { SettingsService, SETTINGS_KEYS } from '../services/settings.service';
const FORMAT_TO_ISO_FORMAT = {
"longDate": "y-MM-dd",
"mediumDate": "yy-MM-dd",
"shortDate": "yy-MM-dd"
"mediumDate": "y-MM-dd",
"shortDate": "y-MM-dd"
}
@Pipe({

View File

@@ -26,6 +26,7 @@ export const SETTINGS_KEYS = {
DOCUMENT_LIST_SIZE: 'general-settings:documentListSize',
DARK_MODE_USE_SYSTEM: 'general-settings:dark-mode:use-system',
DARK_MODE_ENABLED: 'general-settings:dark-mode:enabled',
DARK_MODE_THUMB_INVERTED: 'general-settings:dark-mode:thumb-inverted',
USE_NATIVE_PDF_VIEWER: 'general-settings:document-details:native-pdf-viewer',
DATE_LOCALE: 'general-settings:date-display:date-locale',
DATE_FORMAT: 'general-settings:date-display:date-format',
@@ -41,6 +42,7 @@ const SETTINGS: PaperlessSettings[] = [
{key: SETTINGS_KEYS.DOCUMENT_LIST_SIZE, type: "number", default: 50},
{key: SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, type: "boolean", default: true},
{key: SETTINGS_KEYS.DARK_MODE_ENABLED, type: "boolean", default: false},
{key: SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED, type: "boolean", default: true},
{key: SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, type: "boolean", default: false},
{key: SETTINGS_KEYS.DATE_LOCALE, type: "string", default: ""},
{key: SETTINGS_KEYS.DATE_FORMAT, type: "string", default: "mediumDate"},
@@ -87,10 +89,16 @@ export class SettingsService {
return [
{code: "en-us", name: $localize`English (US)`, englishName: "English (US)", dateInputFormat: "mm/dd/yyyy"},
{code: "en-gb", name: $localize`English (GB)`, englishName: "English (GB)", dateInputFormat: "dd/mm/yyyy"},
{code: "de", name: $localize`German`, englishName: "German", dateInputFormat: "dd.mm.yyyy"},
{code: "nl", name: $localize`Dutch`, englishName: "Dutch", dateInputFormat: "dd-mm-yyyy"},
{code: "fr", name: $localize`French`, englishName: "French", dateInputFormat: "dd/mm/yyyy"},
{code: "pt-br", name: $localize`Portuguese (Brazil)`, englishName: "Portuguese (Brazil)", dateInputFormat: "dd/mm/yyyy"}
{code: "de-de", name: $localize`German`, englishName: "German", dateInputFormat: "dd.mm.yyyy"},
{code: "nl-nl", name: $localize`Dutch`, englishName: "Dutch", dateInputFormat: "dd-mm-yyyy"},
{code: "fr-fr", name: $localize`French`, englishName: "French", dateInputFormat: "dd/mm/yyyy"},
{code: "pt-pt", name: $localize`Portuguese`, englishName: "Portuguese", dateInputFormat: "dd/mm/yyyy"},
{code: "pt-br", name: $localize`Portuguese (Brazil)`, englishName: "Portuguese (Brazil)", dateInputFormat: "dd/mm/yyyy"},
{code: "it-it", name: $localize`Italian`, englishName: "Italian", dateInputFormat: "dd/mm/yyyy"},
{code: "ro-ro", name: $localize`Romanian`, englishName: "Romanian", dateInputFormat: "dd.mm.yyyy"},
{code: "ru-ru", name: $localize`Russian`, englishName: "Russian", dateInputFormat: "dd.mm.yyyy"},
{code: "es-es", name: $localize`Spanish`, englishName: "Spanish", dateInputFormat: "dd/mm/yyyy"},
]
}

View File

@@ -0,0 +1,48 @@
function componentToHex(c) {
var hex = Math.floor(c).toString(16)
return hex.length == 1 ? "0" + hex : hex
}
/**
* https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
*
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* @param Number h The hue
* @param Number s The saturation
* @param Number l The lightness
* @return Array The RGB representation
*/
function hslToRgb(h, s, l){
var r, g, b
if(s == 0){
r = g = b = l // achromatic
}else{
function hue2rgb(p, q, t){
if(t < 0) t += 1
if(t > 1) t -= 1
if(t < 1/6) return p + (q - p) * 6 * t
if(t < 1/2) return q
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6
return p
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s
var p = 2 * l - q
r = hue2rgb(p, q, h + 1/3)
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h - 1/3)
}
return [r * 255, g * 255, b * 255]
}
export function randomColor() {
let rgb = hslToRgb(Math.random(), 0.6, Math.random() * 0.4 + 0.4)
return `#${componentToHex(rgb[0])}${componentToHex(rgb[1])}${componentToHex(rgb[2])}`
}

View File

@@ -1,9 +1,9 @@
export const environment = {
production: true,
apiBaseUrl: "/api/",
apiVersion: "1",
apiVersion: "2",
appTitle: "Paperless-ng",
version: "1.2.1",
version: "1.3.2",
webSocketHost: window.location.host,
webSocketProtocol: (window.location.protocol == "https:" ? "wss:" : "ws:")
};

View File

@@ -5,7 +5,7 @@
export const environment = {
production: false,
apiBaseUrl: "http://localhost:8000/api/",
apiVersion: "1",
apiVersion: "2",
appTitle: "Paperless-ng",
version: "DEVELOPMENT",
webSocketHost: "localhost:8000",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
$primary-dark-mode: #45973a;
$danger-dark-mode: #b71631;
$bg-dark-mode: #161618;
$bg-dark-mode-accent: #21262d;
$bg-light-dark-mode: #1c1c1f;
$text-color-dark-mode: #abb2bf;
$text-color-dark-mode-accent: lighten($text-color-dark-mode, 10%);
@@ -63,6 +64,10 @@ $border-color-dark-mode: #47494f;
background-color: $bg-dark-mode;
color: $text-color-dark-mode;
border-color: $border-color-dark-mode $border-color-dark-mode $bg-dark-mode;
.close {
background-color: inherit !important;
}
}
&:hover {
@@ -71,6 +76,10 @@ $border-color-dark-mode: #47494f;
}
}
.page-item.active .page-link {
background-color: darken($primary-dark-mode, 10%);
}
.nav-tabs {
border-color: $border-color-dark-mode;
@@ -139,15 +148,18 @@ $border-color-dark-mode: #47494f;
.doc-img {
mix-blend-mode: normal;
filter: invert(95%) hue-rotate(180deg);
border-radius: 0;
border-color: $bg-dark-mode;
filter: invert(10%);
&.border-right {
border-right: none !important;
}
}
.doc-img.inverted {
filter: invert(95%) hue-rotate(180deg);
}
.card-selected .doc-img {
mix-blend-mode: luminosity;
}
@@ -218,7 +230,7 @@ $border-color-dark-mode: #47494f;
}
.btn-outline-secondary {
border-color: $text-color-dark-mode;
border-color: darken($text-color-dark-mode, 30%);
color: $text-color-dark-mode;
&:not(:disabled):not(.disabled):hover {
@@ -271,6 +283,10 @@ $border-color-dark-mode: #47494f;
background-color: $bg-dark-mode !important;
}
.card-footer button:hover {
color: $primary-dark-mode !important;
}
.form-control:not(.is-invalid):not(.btn),
input:not(.is-invalid),
textarea:not(.is-invalid) {
@@ -377,6 +393,28 @@ $border-color-dark-mode: #47494f;
background-color: darken($primary-dark-mode, 5%) !important;
}
.popover {
.popover-header,
.popover-body {
background-color: $bg-dark-mode-accent;
border-color: $border-color-dark-mode;
}
}
$placements: 'top', 'right', 'bottom', 'left';
@each $placement in $placements {
.bs-popover-#{$placement} > .arrow::after,
.bs-popover-auto[x-placement^=#{$placement}] > .arrow::after {
border-#{$placement}-color: $bg-dark-mode-accent;
}
}
.bs-popover-bottom .popover-header::before,
.bs-popover-auto[x-placement^=bottom] .popover-header::before {
border-bottom-color: $bg-dark-mode-accent;
}
.ngb-dp-header,
.ngb-dp-weekdays,
.ngb-dp-month {

Binary file not shown.

View File

@@ -19,12 +19,12 @@ class TagAdmin(admin.ModelAdmin):
list_display = (
"name",
"colour",
"color",
"match",
"matching_algorithm"
)
list_filter = ("colour", "matching_algorithm")
list_editable = ("colour", "match", "matching_algorithm")
list_filter = ("color", "matching_algorithm")
list_editable = ("color", "match", "matching_algorithm")
class DocumentTypeAdmin(admin.ModelAdmin):

View File

@@ -123,10 +123,11 @@ class DocumentClassifier(object):
m.update(y.to_bytes(4, 'little', signed=True))
labels_correspondent.append(y)
tags = [tag.pk for tag in doc.tags.filter(
tags = sorted([tag.pk for tag in doc.tags.filter(
matching_algorithm=MatchingModel.MATCH_AUTO
)]
m.update(bytearray(tags))
)])
for tag in tags:
m.update(tag.to_bytes(4, 'little', signed=True))
labels_tags.append(tags)
if not data:

View File

@@ -1,3 +1,4 @@
from django.db.models import Q
from django_filters.rest_framework import BooleanFilter, FilterSet, Filter
from .models import Correspondent, Document, Tag, DocumentType, Log
@@ -70,6 +71,16 @@ class InboxFilter(Filter):
return qs
class TitleContentFilter(Filter):
def filter(self, qs, value):
if value:
return qs.filter(Q(title__icontains=value) |
Q(content__icontains=value))
else:
return qs
class DocumentFilterSet(FilterSet):
is_tagged = BooleanFilter(
@@ -85,6 +96,8 @@ class DocumentFilterSet(FilterSet):
is_in_inbox = InboxFilter()
title_content = TitleContentFilter()
class Meta:
model = Document
fields = {

View File

@@ -6,15 +6,18 @@ import time
import tqdm
from django.conf import settings
from django.contrib.auth.models import User
from django.core import serializers
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from filelock import FileLock
from documents.models import Document, Correspondent, Tag, DocumentType
from documents.models import Document, Correspondent, Tag, DocumentType, \
SavedView, SavedViewFilterRule
from documents.settings import EXPORTER_FILE_NAME, EXPORTER_THUMBNAIL_NAME, \
EXPORTER_ARCHIVE_NAME
from paperless.db import GnuPG
from paperless_mail.models import MailAccount, MailRule
from ...file_handling import generate_filename, delete_empty_directories
@@ -105,6 +108,21 @@ class Command(BaseCommand):
serializers.serialize("json", documents))
manifest += document_manifest
manifest += json.loads(serializers.serialize(
"json", MailAccount.objects.all()))
manifest += json.loads(serializers.serialize(
"json", MailRule.objects.all()))
manifest += json.loads(serializers.serialize(
"json", SavedView.objects.all()))
manifest += json.loads(serializers.serialize(
"json", SavedViewFilterRule.objects.all()))
manifest += json.loads(serializers.serialize(
"json", User.objects.all()))
# 3. Export files from each document
for index, document_dict in tqdm.tqdm(enumerate(document_manifest),
total=len(document_manifest)):

View File

@@ -90,7 +90,7 @@ def matches(matching_model, document):
elif matching_model.matching_algorithm == MatchingModel.MATCH_LITERAL:
result = bool(re.search(
rf"\b{matching_model.match}\b",
rf"\b{re.escape(matching_model.match)}\b",
document_content,
**search_kwargs
))
@@ -161,6 +161,9 @@ def _split_match(matching_model):
findterms = re.compile(r'"([^"]+)"|(\S+)').findall
normspace = re.compile(r"\s+").sub
return [
normspace(" ", (t[0] or t[1]).strip()).replace(" ", r"\s+")
# normspace(" ", (t[0] or t[1]).strip()).replace(" ", r"\s+")
re.escape(
normspace(" ", (t[0] or t[1]).strip())
).replace(r"\ ", r"\s+")
for t in findterms(matching_model.match)
]

View File

@@ -0,0 +1,70 @@
# Generated by Django 3.1.4 on 2020-12-02 21:43
from django.db import migrations, models
COLOURS_OLD = {
1: "#a6cee3",
2: "#1f78b4",
3: "#b2df8a",
4: "#33a02c",
5: "#fb9a99",
6: "#e31a1c",
7: "#fdbf6f",
8: "#ff7f00",
9: "#cab2d6",
10: "#6a3d9a",
11: "#b15928",
12: "#000000",
13: "#cccccc",
}
def forward(apps, schema_editor):
Tag = apps.get_model('documents', 'Tag')
for tag in Tag.objects.all():
colour_old_id = tag.colour_old
rgb = COLOURS_OLD[colour_old_id]
tag.color = rgb
tag.save()
def reverse(apps, schema_editor):
Tag = apps.get_model('documents', 'Tag')
def _get_colour_id(rdb):
for idx, rdbx in COLOURS_OLD.items():
if rdbx == rdb:
return idx
# Return colour 1 if we can't match anything
return 1
for tag in Tag.objects.all():
colour_id = _get_colour_id(tag.color)
tag.colour_old = colour_id
tag.save()
class Migration(migrations.Migration):
dependencies = [
('documents', '1012_fix_archive_files'),
]
operations = [
migrations.RenameField(
model_name='tag',
old_name='colour',
new_name='colour_old',
),
migrations.AddField(
model_name='tag',
name='color',
field=models.CharField(default='#a6cee3', max_length=7, verbose_name='color'),
),
migrations.RunPython(forward, reverse),
migrations.RemoveField(
model_name='tag',
name='colour_old',
)
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-02-28 15:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('documents', '1013_migrate_tag_colour'),
]
operations = [
migrations.AlterField(
model_name='savedviewfilterrule',
name='rule_type',
field=models.PositiveIntegerField(choices=[(0, 'title contains'), (1, 'content contains'), (2, 'ASN is'), (3, 'correspondent is'), (4, 'document type is'), (5, 'is in inbox'), (6, 'has tag'), (7, 'has any tag'), (8, 'created before'), (9, 'created after'), (10, 'created year is'), (11, 'created month is'), (12, 'created day is'), (13, 'added before'), (14, 'added after'), (15, 'modified before'), (16, 'modified after'), (17, 'does not have tag'), (18, 'does not have ASN'), (19, 'title or content contains')], verbose_name='rule type'),
),
]

View File

@@ -77,25 +77,11 @@ class Correspondent(MatchingModel):
class Tag(MatchingModel):
COLOURS = (
(1, "#a6cee3"),
(2, "#1f78b4"),
(3, "#b2df8a"),
(4, "#33a02c"),
(5, "#fb9a99"),
(6, "#e31a1c"),
(7, "#fdbf6f"),
(8, "#ff7f00"),
(9, "#cab2d6"),
(10, "#6a3d9a"),
(11, "#b15928"),
(12, "#000000"),
(13, "#cccccc")
)
colour = models.PositiveIntegerField(
color = models.CharField(
_("color"),
choices=COLOURS, default=1)
max_length=7,
default="#a6cee3"
)
is_inbox_tag = models.BooleanField(
_("is inbox tag"),
@@ -399,6 +385,8 @@ class SavedViewFilterRule(models.Model):
(15, _("modified before")),
(16, _("modified after")),
(17, _("does not have tag")),
(18, _("does not have ASN")),
(19, _("title or content contains")),
]
saved_view = models.ForeignKey(

View File

@@ -143,6 +143,46 @@ def run_convert(input_file,
raise ParseError("Convert failed at {}".format(args))
def get_default_thumbnail():
return os.path.join(os.path.dirname(__file__), "resources", "document.png")
def make_thumbnail_from_pdf_gs_fallback(in_path, temp_dir, logging_group=None):
out_path = os.path.join(temp_dir, "convert_gs.png")
# if convert fails, fall back to extracting
# the first PDF page as a PNG using Ghostscript
logger.warning(
"Thumbnail generation with ImageMagick failed, falling back "
"to ghostscript. Check your /etc/ImageMagick-x/policy.xml!",
extra={'group': logging_group}
)
gs_out_path = os.path.join(temp_dir, "gs_out.png")
cmd = [settings.GS_BINARY,
"-q",
"-sDEVICE=pngalpha",
"-o", gs_out_path,
in_path]
try:
if not subprocess.Popen(cmd).wait() == 0:
raise ParseError("Thumbnail (gs) failed at {}".format(cmd))
# then run convert on the output from gs
run_convert(density=300,
scale="500x5000>",
alpha="remove",
strip=True,
trim=False,
auto_orient=True,
input_file=gs_out_path,
output_file=out_path,
logging_group=logging_group)
return out_path
except ParseError:
return get_default_thumbnail()
def make_thumbnail_from_pdf(in_path, temp_dir, logging_group=None):
"""
The thumbnail of a PDF is just a 500px wide image of the first page.
@@ -161,31 +201,8 @@ def make_thumbnail_from_pdf(in_path, temp_dir, logging_group=None):
output_file=out_path,
logging_group=logging_group)
except ParseError:
# if convert fails, fall back to extracting
# the first PDF page as a PNG using Ghostscript
logger.warning(
"Thumbnail generation with ImageMagick failed, falling back "
"to ghostscript. Check your /etc/ImageMagick-x/policy.xml!",
extra={'group': logging_group}
)
gs_out_path = os.path.join(temp_dir, "gs_out.png")
cmd = [settings.GS_BINARY,
"-q",
"-sDEVICE=pngalpha",
"-o", gs_out_path,
in_path]
if not subprocess.Popen(cmd).wait() == 0:
raise ParseError("Thumbnail (gs) failed at {}".format(cmd))
# then run convert on the output from gs
run_convert(density=300,
scale="500x5000>",
alpha="remove",
strip=True,
trim=False,
auto_orient=True,
input_file=gs_out_path,
output_file=out_path,
logging_group=logging_group)
out_path = make_thumbnail_from_pdf_gs_fallback(
in_path, temp_dir, logging_group)
return out_path

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,6 +1,7 @@
import re
import magic
import math
from django.utils.text import slugify
from rest_framework import serializers
from rest_framework.fields import SerializerMethodField
@@ -49,7 +50,7 @@ class MatchingModelSerializer(serializers.ModelSerializer):
re.compile(match)
except Exception as e:
raise serializers.ValidationError(
_("Invalid regular expresssion: %(error)s") %
_("Invalid regular expression: %(error)s") %
{'error': str(e)}
)
return match
@@ -88,7 +89,40 @@ class DocumentTypeSerializer(MatchingModelSerializer):
)
class TagSerializer(MatchingModelSerializer):
class ColorField(serializers.Field):
COLOURS = (
(1, "#a6cee3"),
(2, "#1f78b4"),
(3, "#b2df8a"),
(4, "#33a02c"),
(5, "#fb9a99"),
(6, "#e31a1c"),
(7, "#fdbf6f"),
(8, "#ff7f00"),
(9, "#cab2d6"),
(10, "#6a3d9a"),
(11, "#b15928"),
(12, "#000000"),
(13, "#cccccc")
)
def to_internal_value(self, data):
for id, color in self.COLOURS:
if id == data:
return color
raise serializers.ValidationError()
def to_representation(self, value):
for id, color in self.COLOURS:
if color == value:
return id
return 1
class TagSerializerVersion1(MatchingModelSerializer):
colour = ColorField(source='color', default="#a6cee3")
class Meta:
model = Tag
@@ -105,6 +139,45 @@ class TagSerializer(MatchingModelSerializer):
)
class TagSerializer(MatchingModelSerializer):
def get_text_color(self, obj):
try:
h = obj.color.lstrip('#')
rgb = tuple(int(h[i:i + 2], 16)/256 for i in (0, 2, 4))
luminance = math.sqrt(
0.299 * math.pow(rgb[0], 2) +
0.587 * math.pow(rgb[1], 2) +
0.114 * math.pow(rgb[2], 2)
)
return "#ffffff" if luminance < 0.53 else "#000000"
except ValueError:
return "#000000"
text_color = serializers.SerializerMethodField()
class Meta:
model = Tag
fields = (
"id",
"slug",
"name",
"color",
"text_color",
"match",
"matching_algorithm",
"is_insensitive",
"is_inbox_tag",
"document_count"
)
def validate_color(self, color):
regex = r"#[0-9a-fA-F]{6}"
if not re.match(regex, color):
raise serializers.ValidationError(_("Invalid color."))
return color
class CorrespondentField(serializers.PrimaryKeyRelatedField):
def get_queryset(self):
return Correspondent.objects.all()

View File

@@ -15,7 +15,7 @@
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="manifest" href="{% static webmanifest %}">
<link rel="stylesheet" href="{% static styles_css %}">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
<link rel="apple-touch-icon" href="{% static apple_touch_icon %}">
</head>
<body>
<app-root>{% translate "Paperless-ng is loading..." %}</app-root>

View File

@@ -270,6 +270,30 @@ class TestDocumentApi(DirectoriesMixin, APITestCase):
results = response.data['results']
self.assertEqual(len(results), 0)
def test_documents_title_content_filter(self):
doc1 = Document.objects.create(title="title A", content="content A", checksum="A", mime_type="application/pdf")
doc2 = Document.objects.create(title="title B", content="content A", checksum="B", mime_type="application/pdf")
doc3 = Document.objects.create(title="title A", content="content B", checksum="C", mime_type="application/pdf")
doc4 = Document.objects.create(title="title B", content="content B", checksum="D", mime_type="application/pdf")
response = self.client.get("/api/documents/?title_content=A")
self.assertEqual(response.status_code, 200)
results = response.data['results']
self.assertEqual(len(results), 3)
self.assertCountEqual([results[0]['id'], results[1]['id'], results[2]['id']], [doc1.id, doc2.id, doc3.id])
response = self.client.get("/api/documents/?title_content=B")
self.assertEqual(response.status_code, 200)
results = response.data['results']
self.assertEqual(len(results), 3)
self.assertCountEqual([results[0]['id'], results[1]['id'], results[2]['id']], [doc2.id, doc3.id, doc4.id])
response = self.client.get("/api/documents/?title_content=X")
self.assertEqual(response.status_code, 200)
results = response.data['results']
self.assertEqual(len(results), 0)
def test_search_no_query(self):
response = self.client.get("/api/search/")
results = response.data['results']
@@ -807,6 +831,69 @@ class TestDocumentApi(DirectoriesMixin, APITestCase):
}, format='json')
self.assertEqual(response.status_code, 201, endpoint)
def test_tag_color_default(self):
response = self.client.post("/api/tags/", {
"name": "tag"
}, format="json")
self.assertEqual(response.status_code, 201)
self.assertEqual(Tag.objects.get(id=response.data['id']).color, "#a6cee3")
self.assertEqual(self.client.get(f"/api/tags/{response.data['id']}/", format="json").data['colour'], 1)
def test_tag_color(self):
response = self.client.post("/api/tags/", {
"name": "tag",
"colour": 3
}, format="json")
self.assertEqual(response.status_code, 201)
self.assertEqual(Tag.objects.get(id=response.data['id']).color, "#b2df8a")
self.assertEqual(self.client.get(f"/api/tags/{response.data['id']}/", format="json").data['colour'], 3)
def test_tag_color_invalid(self):
response = self.client.post("/api/tags/", {
"name": "tag",
"colour": 34
}, format="json")
self.assertEqual(response.status_code, 400)
def test_tag_color_custom(self):
tag = Tag.objects.create(name="test", color="#abcdef")
self.assertEqual(self.client.get(f"/api/tags/{tag.id}/", format="json").data['colour'], 1)
class TestDocumentApiV2(DirectoriesMixin, APITestCase):
def setUp(self):
super(TestDocumentApiV2, self).setUp()
self.user = User.objects.create_superuser(username="temp_admin")
self.client.force_login(user=self.user)
self.client.defaults['HTTP_ACCEPT'] = 'application/json; version=2'
def test_tag_validate_color(self):
self.assertEqual(self.client.post("/api/tags/", {"name": "test", "color": "#12fFaA"}, format="json").status_code, 201)
self.assertEqual(self.client.post("/api/tags/", {"name": "test1", "color": "abcdef"}, format="json").status_code, 400)
self.assertEqual(self.client.post("/api/tags/", {"name": "test2", "color": "#abcdfg"}, format="json").status_code, 400)
self.assertEqual(self.client.post("/api/tags/", {"name": "test3", "color": "#asd"}, format="json").status_code, 400)
self.assertEqual(self.client.post("/api/tags/", {"name": "test4", "color": "#12121212"}, format="json").status_code, 400)
def test_tag_text_color(self):
t = Tag.objects.create(name="tag1", color="#000000")
self.assertEqual(self.client.get(f"/api/tags/{t.id}/", format="json").data['text_color'], "#ffffff")
t.color = "#ffffff"
t.save()
self.assertEqual(self.client.get(f"/api/tags/{t.id}/", format="json").data['text_color'], "#000000")
t.color = "asdf"
t.save()
self.assertEqual(self.client.get(f"/api/tags/{t.id}/", format="json").data['text_color'], "#000000")
t.color = "123"
t.save()
self.assertEqual(self.client.get(f"/api/tags/{t.id}/", format="json").data['text_color'], "#000000")
class TestBulkEdit(DirectoriesMixin, APITestCase):
@@ -1293,3 +1380,16 @@ class TestApiAuth(APITestCase):
self.assertEqual(self.client.get("/api/documents/bulk_edit/").status_code, 401)
self.assertEqual(self.client.get("/api/documents/bulk_download/").status_code, 401)
self.assertEqual(self.client.get("/api/documents/selection_data/").status_code, 401)
def test_api_version_no_auth(self):
response = self.client.get("/api/")
self.assertNotIn("X-Api-Version", response)
self.assertNotIn("X-Version", response)
def test_api_version_with_auth(self):
user = User.objects.create_superuser(username="test")
self.client.force_login(user)
response = self.client.get("/api/")
self.assertIn("X-Api-Version", response)
self.assertIn("X-Version", response)

View File

@@ -69,7 +69,7 @@ class TestExportImport(DirectoriesMixin, TestCase):
manifest = self._do_export(use_filename_format=use_filename_format)
self.assertEqual(len(manifest), 7)
self.assertEqual(len(manifest), 8)
self.assertEqual(len(list(filter(lambda e: e['model'] == 'documents.document', manifest))), 4)
self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json")))

View File

@@ -0,0 +1,37 @@
from documents.tests.utils import DirectoriesMixin, TestMigrations
class TestMigrateTagColor(DirectoriesMixin, TestMigrations):
migrate_from = '1012_fix_archive_files'
migrate_to = '1013_migrate_tag_colour'
def setUpBeforeMigration(self, apps):
Tag = apps.get_model("documents", "Tag")
self.t1_id = Tag.objects.create(name="tag1").id
self.t2_id = Tag.objects.create(name="tag2", colour=1).id
self.t3_id = Tag.objects.create(name="tag3", colour=5).id
def testMimeTypesMigrated(self):
Tag = self.apps.get_model('documents', 'Tag')
self.assertEqual(Tag.objects.get(id=self.t1_id).color, "#a6cee3")
self.assertEqual(Tag.objects.get(id=self.t2_id).color, "#a6cee3")
self.assertEqual(Tag.objects.get(id=self.t3_id).color, "#fb9a99")
class TestMigrateTagColorBackwards(DirectoriesMixin, TestMigrations):
migrate_from = '1013_migrate_tag_colour'
migrate_to = '1012_fix_archive_files'
def setUpBeforeMigration(self, apps):
Tag = apps.get_model("documents", "Tag")
self.t1_id = Tag.objects.create(name="tag1").id
self.t2_id = Tag.objects.create(name="tag2", color="#cab2d6").id
self.t3_id = Tag.objects.create(name="tag3", color="#123456").id
def testMimeTypesReverted(self):
Tag = self.apps.get_model('documents', 'Tag')
self.assertEqual(Tag.objects.get(id=self.t1_id).colour, 1)
self.assertEqual(Tag.objects.get(id=self.t2_id).colour, 9)
self.assertEqual(Tag.objects.get(id=self.t3_id).colour, 1)

View File

@@ -15,7 +15,7 @@ class TestViews(TestCase):
def test_index(self):
self.client.force_login(self.user)
for (language_given, language_actual) in [("", "en-US"), ("en-US", "en-US"), ("de", "de"), ("en", "en-US"), ("en-us", "en-US"), ("fr", "fr"), ("jp", "en-US")]:
for (language_given, language_actual) in [("", "en-US"), ("en-US", "en-US"), ("de", "de-DE"), ("en", "en-US"), ("en-us", "en-US"), ("fr", "fr-FR"), ("jp", "en-US")]:
if language_given:
self.client.cookies.load({settings.LANGUAGE_COOKIE_NAME: language_given})
elif settings.LANGUAGE_COOKIE_NAME in self.client.cookies.keys():

View File

@@ -18,6 +18,7 @@ from django_q.tasks import async_task
from rest_framework import parsers
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import (
DestroyModelMixin,
ListModelMixin,
@@ -50,6 +51,7 @@ from .parsers import get_parser_class_for_mime_type
from .serialisers import (
CorrespondentSerializer,
DocumentSerializer,
TagSerializerVersion1,
TagSerializer,
DocumentTypeSerializer,
PostDocumentSerializer,
@@ -89,6 +91,7 @@ class IndexView(TemplateView):
context['polyfills_js'] = f"frontend/{self.get_language()}/polyfills.js" # NOQA: E501
context['main_js'] = f"frontend/{self.get_language()}/main.js"
context['webmanifest'] = f"frontend/{self.get_language()}/manifest.webmanifest" # NOQA: E501
context['apple_touch_icon'] = f"frontend/{self.get_language()}/apple-touch-icon.png" # NOQA: E501
return context
@@ -118,7 +121,12 @@ class TagViewSet(ModelViewSet):
queryset = Tag.objects.annotate(
document_count=Count('documents')).order_by(Lower('name'))
serializer_class = TagSerializer
def get_serializer_class(self):
if int(self.request.version) == 1:
return TagSerializerVersion1
else:
return TagSerializer
pagination_class = StandardPagination
permission_classes = (IsAuthenticated,)
filter_backends = (DjangoFilterBackend, OrderingFilter)
@@ -359,23 +367,12 @@ class SavedViewViewSet(ModelViewSet):
serializer.save(user=self.request.user)
class BulkEditView(APIView):
class BulkEditView(GenericAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = BulkEditSerializer
parser_classes = (parsers.JSONParser,)
def get_serializer_context(self):
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}
def get_serializer(self, *args, **kwargs):
kwargs['context'] = self.get_serializer_context()
return self.serializer_class(*args, **kwargs)
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
@@ -392,23 +389,12 @@ class BulkEditView(APIView):
return HttpResponseBadRequest(str(e))
class PostDocumentView(APIView):
class PostDocumentView(GenericAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = PostDocumentSerializer
parser_classes = (parsers.MultiPartParser,)
def get_serializer_context(self):
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}
def get_serializer(self, *args, **kwargs):
kwargs['context'] = self.get_serializer_context()
return self.serializer_class(*args, **kwargs)
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
@@ -446,23 +432,12 @@ class PostDocumentView(APIView):
return Response("OK")
class SelectionDataView(APIView):
class SelectionDataView(GenericAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = DocumentListSerializer
parser_classes = (parsers.MultiPartParser, parsers.JSONParser)
def get_serializer_context(self):
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}
def get_serializer(self, *args, **kwargs):
kwargs['context'] = self.get_serializer_context()
return self.serializer_class(*args, **kwargs)
def post(self, request, format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
@@ -613,23 +588,12 @@ class StatisticsView(APIView):
})
class BulkDownloadView(APIView):
class BulkDownloadView(GenericAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = BulkDownloadSerializer
parser_classes = (parsers.JSONParser,)
def get_serializer_context(self):
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}
def get_serializer(self, *args, **kwargs):
kwargs['context'] = self.get_serializer_context()
return self.serializer_class(*args, **kwargs)
def post(self, request, format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)

View File

@@ -1,335 +1,339 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# Štěpán Šebestian <mys.orangeorange0123@gmail.com>, 2021
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Project-Id-Version: paperless-ng\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-28 22:02+0100\n"
"PO-Revision-Date: 2020-12-30 19:27+0000\n"
"Last-Translator: Štěpán Šebestian <mys.orangeorange0123@gmail.com>, 2021\n"
"Language-Team: Czech (https://www.transifex.com/paperless/teams/115905/cs/)\n"
"POT-Creation-Date: 2021-03-17 22:31+0100\n"
"PO-Revision-Date: 2021-03-17 21:47\n"
"Last-Translator: \n"
"Language-Team: Czech\n"
"Language: cs_CZ\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cs\n"
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n"
"X-Crowdin-Project: paperless-ng\n"
"X-Crowdin-Project-ID: 434940\n"
"X-Crowdin-Language: cs\n"
"X-Crowdin-File: /dev/src/locale/en_US/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 54\n"
#: documents/apps.py:10
msgid "Documents"
msgstr "Dokumenty"
#: documents/models.py:33
#: documents/models.py:32
msgid "Any word"
msgstr "Jakékoliv slovo"
#: documents/models.py:34
#: documents/models.py:33
msgid "All words"
msgstr "Všechna slova"
#: documents/models.py:35
#: documents/models.py:34
msgid "Exact match"
msgstr "Přesná shoda"
#: documents/models.py:36
#: documents/models.py:35
msgid "Regular expression"
msgstr "Regulární výraz"
#: documents/models.py:37
#: documents/models.py:36
msgid "Fuzzy word"
msgstr "Fuzzy slovo"
#: documents/models.py:38
#: documents/models.py:37
msgid "Automatic"
msgstr "Automatický"
#: documents/models.py:42 documents/models.py:352 paperless_mail/models.py:25
#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25
#: paperless_mail/models.py:109
msgid "name"
msgstr "název"
#: documents/models.py:46
#: documents/models.py:45
msgid "match"
msgstr "shoda"
#: documents/models.py:50
#: documents/models.py:49
msgid "matching algorithm"
msgstr "algoritmus pro shodu"
#: documents/models.py:56
#: documents/models.py:55
msgid "is insensitive"
msgstr "je ignorováno"
#: documents/models.py:75 documents/models.py:135
#: documents/models.py:74 documents/models.py:120
msgid "correspondent"
msgstr "korespondent"
#: documents/models.py:76
#: documents/models.py:75
msgid "correspondents"
msgstr "korespondenti"
#: documents/models.py:98
#: documents/models.py:81
msgid "color"
msgstr "barva"
#: documents/models.py:102
#: documents/models.py:87
msgid "is inbox tag"
msgstr "tag přichozí"
#: documents/models.py:104
msgid ""
"Marks this tag as an inbox tag: All newly consumed documents will be tagged "
"with inbox tags."
msgstr ""
"Označí tento tag jako tag pro příchozí: Všechny nově zkonzumované dokumenty "
"budou označeny tagem pro přichozí"
#: documents/models.py:89
msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags."
msgstr "Označí tento tag jako tag pro příchozí: Všechny nově zkonzumované dokumenty budou označeny tagem pro přichozí"
#: documents/models.py:109
#: documents/models.py:94
msgid "tag"
msgstr "tag"
#: documents/models.py:110 documents/models.py:166
#: documents/models.py:95 documents/models.py:151
msgid "tags"
msgstr "tagy"
#: documents/models.py:116 documents/models.py:148
#: documents/models.py:101 documents/models.py:133
msgid "document type"
msgstr "typ dokumentu"
#: documents/models.py:117
#: documents/models.py:102
msgid "document types"
msgstr "typy dokumentu"
#: documents/models.py:125
#: documents/models.py:110
msgid "Unencrypted"
msgstr "Nešifrované"
#: documents/models.py:126
#: documents/models.py:111
msgid "Encrypted with GNU Privacy Guard"
msgstr "Šifrované pomocí GNU Privacy Guard"
#: documents/models.py:139
#: documents/models.py:124
msgid "title"
msgstr "titulek"
#: documents/models.py:152
#: documents/models.py:137
msgid "content"
msgstr "obsah"
#: documents/models.py:154
msgid ""
"The raw, text-only data of the document. This field is primarily used for "
"searching."
msgstr ""
"Nezpracovaná, pouze textová data dokumentu. Toto pole je používáno především"
" pro vyhledávání."
#: documents/models.py:139
msgid "The raw, text-only data of the document. This field is primarily used for searching."
msgstr "Nezpracovaná, pouze textová data dokumentu. Toto pole je používáno především pro vyhledávání."
#: documents/models.py:159
#: documents/models.py:144
msgid "mime type"
msgstr "mime typ"
#: documents/models.py:170
#: documents/models.py:155
msgid "checksum"
msgstr "kontrolní součet"
#: documents/models.py:174
#: documents/models.py:159
msgid "The checksum of the original document."
msgstr "Kontrolní součet původního dokumentu"
#: documents/models.py:178
#: documents/models.py:163
msgid "archive checksum"
msgstr "kontrolní součet archivu"
#: documents/models.py:183
#: documents/models.py:168
msgid "The checksum of the archived document."
msgstr "Kontrolní součet archivovaného dokumentu."
#: documents/models.py:187 documents/models.py:330
#: documents/models.py:172 documents/models.py:328
msgid "created"
msgstr "vytvořeno"
#: documents/models.py:191
#: documents/models.py:176
msgid "modified"
msgstr "upraveno"
#: documents/models.py:195
#: documents/models.py:180
msgid "storage type"
msgstr "typ úložiště"
#: documents/models.py:203
#: documents/models.py:188
msgid "added"
msgstr "přidáno"
#: documents/models.py:207
#: documents/models.py:192
msgid "filename"
msgstr "název souboru"
#: documents/models.py:212
#: documents/models.py:198
msgid "Current filename in storage"
msgstr "Aktuální název souboru v úložišti"
#: documents/models.py:216
#: documents/models.py:202
msgid "archive filename"
msgstr ""
#: documents/models.py:208
msgid "Current archive filename in storage"
msgstr ""
#: documents/models.py:212
msgid "archive serial number"
msgstr "sériové číslo archivu"
#: documents/models.py:221
#: documents/models.py:217
msgid "The position of this document in your physical document archive."
msgstr "Pozice dokumentu ve vašem archivu fyzických dokumentů"
#: documents/models.py:227
#: documents/models.py:223
msgid "document"
msgstr "dokument"
#: documents/models.py:228
#: documents/models.py:224
msgid "documents"
msgstr "dokumenty"
#: documents/models.py:313
#: documents/models.py:311
msgid "debug"
msgstr "debug"
#: documents/models.py:314
#: documents/models.py:312
msgid "information"
msgstr "informace"
#: documents/models.py:315
#: documents/models.py:313
msgid "warning"
msgstr "varování"
#: documents/models.py:316
#: documents/models.py:314
msgid "error"
msgstr "chyba"
#: documents/models.py:317
#: documents/models.py:315
msgid "critical"
msgstr "kritická"
#: documents/models.py:321
#: documents/models.py:319
msgid "group"
msgstr "skupina"
#: documents/models.py:324
#: documents/models.py:322
msgid "message"
msgstr "zpráva"
#: documents/models.py:327
#: documents/models.py:325
msgid "level"
msgstr "úroveň"
#: documents/models.py:334
#: documents/models.py:332
msgid "log"
msgstr "záznam"
#: documents/models.py:335
#: documents/models.py:333
msgid "logs"
msgstr "záznamy"
#: documents/models.py:346 documents/models.py:396
#: documents/models.py:344 documents/models.py:396
msgid "saved view"
msgstr "uložený pohled"
#: documents/models.py:347
#: documents/models.py:345
msgid "saved views"
msgstr "uložené pohledy"
#: documents/models.py:350
#: documents/models.py:348
msgid "user"
msgstr "uživatel"
#: documents/models.py:356
#: documents/models.py:354
msgid "show on dashboard"
msgstr "zobrazit v dashboardu"
#: documents/models.py:359
#: documents/models.py:357
msgid "show in sidebar"
msgstr "zobrazit v postranním menu"
#: documents/models.py:363
#: documents/models.py:361
msgid "sort field"
msgstr "pole na řazení"
#: documents/models.py:366
#: documents/models.py:364
msgid "sort reverse"
msgstr "třídit opačně"
#: documents/models.py:372
#: documents/models.py:370
msgid "title contains"
msgstr "titulek obsahuje"
#: documents/models.py:373
#: documents/models.py:371
msgid "content contains"
msgstr "obsah obsahuje"
#: documents/models.py:374
#: documents/models.py:372
msgid "ASN is"
msgstr "ASN je"
#: documents/models.py:375
#: documents/models.py:373
msgid "correspondent is"
msgstr "korespondent je"
#: documents/models.py:376
#: documents/models.py:374
msgid "document type is"
msgstr "typ dokumentu je"
#: documents/models.py:377
#: documents/models.py:375
msgid "is in inbox"
msgstr "je v příchozích"
#: documents/models.py:378
#: documents/models.py:376
msgid "has tag"
msgstr "má tag"
#: documents/models.py:379
#: documents/models.py:377
msgid "has any tag"
msgstr "má jakýkoliv tag"
#: documents/models.py:380
#: documents/models.py:378
msgid "created before"
msgstr "vytvořeno před"
#: documents/models.py:381
#: documents/models.py:379
msgid "created after"
msgstr "vytvořeno po"
#: documents/models.py:382
#: documents/models.py:380
msgid "created year is"
msgstr "rok vytvoření je"
#: documents/models.py:383
#: documents/models.py:381
msgid "created month is"
msgstr "měsíc vytvoření je"
#: documents/models.py:384
#: documents/models.py:382
msgid "created day is"
msgstr "den vytvoření je"
#: documents/models.py:385
#: documents/models.py:383
msgid "added before"
msgstr "přidáno před"
#: documents/models.py:386
#: documents/models.py:384
msgid "added after"
msgstr "přidáno po"
#: documents/models.py:387
#: documents/models.py:385
msgid "modified before"
msgstr "upraveno před"
#: documents/models.py:388
#: documents/models.py:386
msgid "modified after"
msgstr "upraveno po"
#: documents/models.py:389
#: documents/models.py:387
msgid "does not have tag"
msgstr "nemá tag"
#: documents/models.py:388
msgid "does not have ASN"
msgstr ""
#: documents/models.py:389
msgid "title or content contains"
msgstr ""
#: documents/models.py:400
msgid "rule type"
msgstr "typ pravidla"
@@ -346,12 +350,21 @@ msgstr "filtrovací pravidlo"
msgid "filter rules"
msgstr "filtrovací pravidla"
#: documents/serialisers.py:383
#: documents/serialisers.py:53
#, python-format
msgid "Invalid regular expression: %(error)s"
msgstr ""
#: documents/serialisers.py:177
msgid "Invalid color."
msgstr ""
#: documents/serialisers.py:451
#, python-format
msgid "File type %(type)s not supported"
msgstr "Typ souboru %(type)s není podporován"
#: documents/templates/index.html:20
#: documents/templates/index.html:21
msgid "Paperless-ng is loading..."
msgstr "Paperless-ng se načítá..."
@@ -391,23 +404,51 @@ msgstr "Heslo"
msgid "Sign in"
msgstr "Přihlásit se"
#: paperless/settings.py:286
msgid "English"
msgstr "Angličtina"
#: paperless/settings.py:298
msgid "English (US)"
msgstr ""
#: paperless/settings.py:287
#: paperless/settings.py:299
msgid "English (GB)"
msgstr ""
#: paperless/settings.py:300
msgid "German"
msgstr "Němčina"
#: paperless/settings.py:288
#: paperless/settings.py:301
msgid "Dutch"
msgstr "Holandština"
#: paperless/settings.py:289
#: paperless/settings.py:302
msgid "French"
msgstr "Francouzština"
#: paperless/urls.py:114
#: paperless/settings.py:303
msgid "Portuguese (Brazil)"
msgstr ""
#: paperless/settings.py:304
msgid "Portuguese"
msgstr ""
#: paperless/settings.py:305
msgid "Italian"
msgstr ""
#: paperless/settings.py:306
msgid "Romanian"
msgstr ""
#: paperless/settings.py:307
msgid "Russian"
msgstr ""
#: paperless/settings.py:308
msgid "Spanish"
msgstr ""
#: paperless/urls.py:118
msgid "Paperless-ng administration"
msgstr "Správa Paperless-ng"
@@ -416,37 +457,24 @@ msgid "Filter"
msgstr "Filtr"
#: paperless_mail/admin.py:27
msgid ""
"Paperless will only process mails that match ALL of the filters given below."
msgstr ""
"Paperless zpracuje pouze emaily které odpovídají VŠEM níže zadaným filtrům."
msgid "Paperless will only process mails that match ALL of the filters given below."
msgstr "Paperless zpracuje pouze emaily které odpovídají VŠEM níže zadaným filtrům."
#: paperless_mail/admin.py:37
msgid "Actions"
msgstr "Akce"
#: paperless_mail/admin.py:39
msgid ""
"The action applied to the mail. This action is only performed when documents"
" were consumed from the mail. Mails without attachments will remain entirely"
" untouched."
msgstr ""
"Akce provedena na emailu. Tato akce je provedena jen pokud byly dokumenty "
"zkonzumovány z emailu. Emaily bez příloh zůstanou nedotčeny."
msgid "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched."
msgstr "Akce provedena na emailu. Tato akce je provedena jen pokud byly dokumenty zkonzumovány z emailu. Emaily bez příloh zůstanou nedotčeny."
#: paperless_mail/admin.py:46
msgid "Metadata"
msgstr "Metadata"
#: paperless_mail/admin.py:48
msgid ""
"Assign metadata to documents consumed from this rule automatically. If you "
"do not assign tags, types or correspondents here, paperless will still "
"process all matching rules that you have defined."
msgstr ""
"Automaticky přiřadit metadata dokumentům zkonzumovaných z tohoto pravidla. "
"Pokud zde nepřiřadíte tagy, typy nebo korespondenty, paperless stále "
"zpracuje všechna shodující-se pravidla které jste definovali."
msgid "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined."
msgstr "Automaticky přiřadit metadata dokumentům zkonzumovaných z tohoto pravidla. Pokud zde nepřiřadíte tagy, typy nebo korespondenty, paperless stále zpracuje všechna shodující-se pravidla které jste definovali."
#: paperless_mail/apps.py:9
msgid "Paperless mail"
@@ -481,12 +509,8 @@ msgid "IMAP port"
msgstr "IMAP port"
#: paperless_mail/models.py:36
msgid ""
"This is usually 143 for unencrypted and STARTTLS connections, and 993 for "
"SSL connections."
msgstr ""
"Toto je většinou 143 pro nešifrovaná připojení/připojení používající "
"STARTTLS a 993 pro SSL připojení."
msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections."
msgstr "Toto je většinou 143 pro nešifrovaná připojení/připojení používající STARTTLS a 993 pro SSL připojení."
#: paperless_mail/models.py:40
msgid "IMAP security"
@@ -585,13 +609,8 @@ msgid "filter attachment filename"
msgstr "název souboru u přílohy filtru"
#: paperless_mail/models.py:140
msgid ""
"Only consume documents which entirely match this filename if specified. "
"Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr ""
"Konzumovat jen dokumenty které přesně odpovídají tomuto názvu souboru pokud "
"specifikováno. Zástupné znaky jako *.pdf nebo *invoice* jsou povoleny. "
"Nezáleží na velikosti písmen."
msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr "Konzumovat jen dokumenty které přesně odpovídají tomuto názvu souboru pokud specifikováno. Zástupné znaky jako *.pdf nebo *invoice* jsou povoleny. Nezáleží na velikosti písmen."
#: paperless_mail/models.py:146
msgid "maximum age"
@@ -606,12 +625,8 @@ msgid "attachment type"
msgstr "typ přílohy"
#: paperless_mail/models.py:154
msgid ""
"Inline attachments include embedded images, so it's best to combine this "
"option with a filename filter."
msgstr ""
"Vložené přílohy zahrnují vložené obrázky, takže je nejlepší tuto možnost "
"kombinovat s filtrem na název souboru"
msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter."
msgstr "Vložené přílohy zahrnují vložené obrázky, takže je nejlepší tuto možnost kombinovat s filtrem na název souboru"
#: paperless_mail/models.py:159
msgid "action"
@@ -622,12 +637,8 @@ msgid "action parameter"
msgstr "parametr akce"
#: paperless_mail/models.py:167
msgid ""
"Additional parameter for the action selected above, i.e., the target folder "
"of the move to folder action."
msgstr ""
"Další parametr pro výše vybranou akci, napříkad cílová složka akce přesunutí"
" do složky."
msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action."
msgstr "Další parametr pro výše vybranou akci, napříkad cílová složka akce přesunutí do složky."
#: paperless_mail/models.py:173
msgid "assign title from"
@@ -648,3 +659,4 @@ msgstr "přiřadit korespondenta z"
#: paperless_mail/models.py:205
msgid "assign this correspondent"
msgstr "přiřadit tohoto korespondenta"

View File

@@ -1,25 +1,21 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# Jonas Winkler, 2021
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Project-Id-Version: paperless-ng\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-24 16:49+0100\n"
"PO-Revision-Date: 2021-02-16 18:37+0000\n"
"Last-Translator: Jonas Winkler, 2021\n"
"Language-Team: German (https://www.transifex.com/paperless/teams/115905/de/)\n"
"POT-Creation-Date: 2021-03-17 22:31+0100\n"
"PO-Revision-Date: 2021-03-18 13:43\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: paperless-ng\n"
"X-Crowdin-Project-ID: 434940\n"
"X-Crowdin-Language: de\n"
"X-Crowdin-File: /dev/src/locale/en_US/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 54\n"
#: documents/apps.py:10
msgid "Documents"
@@ -49,7 +45,7 @@ msgstr "Ungenaues Wort"
msgid "Automatic"
msgstr "Automatisch"
#: documents/models.py:41 documents/models.py:364 paperless_mail/models.py:25
#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25
#: paperless_mail/models.py:109
msgid "name"
msgstr "Name"
@@ -66,7 +62,7 @@ msgstr "Zuweisungsalgorithmus"
msgid "is insensitive"
msgstr "Groß-/Kleinschreibung irrelevant"
#: documents/models.py:74 documents/models.py:134
#: documents/models.py:74 documents/models.py:120
msgid "correspondent"
msgstr "Korrespondent"
@@ -74,297 +70,301 @@ msgstr "Korrespondent"
msgid "correspondents"
msgstr "Korrespondenten"
#: documents/models.py:97
#: documents/models.py:81
msgid "color"
msgstr "Farbe"
#: documents/models.py:101
#: documents/models.py:87
msgid "is inbox tag"
msgstr "Posteingangs-Tag"
#: documents/models.py:103
msgid ""
"Marks this tag as an inbox tag: All newly consumed documents will be tagged "
"with inbox tags."
msgstr ""
"Markiert das Tag als Posteingangs-Tag. Neue Dokumente werden immer mit "
"diesem Tag versehen."
#: documents/models.py:89
msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags."
msgstr "Markiert das Tag als Posteingangs-Tag. Neue Dokumente werden immer mit diesem Tag versehen."
#: documents/models.py:108
#: documents/models.py:94
msgid "tag"
msgstr "Tag"
#: documents/models.py:109 documents/models.py:165
#: documents/models.py:95 documents/models.py:151
msgid "tags"
msgstr "Tags"
#: documents/models.py:115 documents/models.py:147
#: documents/models.py:101 documents/models.py:133
msgid "document type"
msgstr "Dokumenttyp"
#: documents/models.py:116
#: documents/models.py:102
msgid "document types"
msgstr "Dokumenttypen"
#: documents/models.py:124
#: documents/models.py:110
msgid "Unencrypted"
msgstr "Nicht verschlüsselt"
#: documents/models.py:125
#: documents/models.py:111
msgid "Encrypted with GNU Privacy Guard"
msgstr "Verschlüsselt mit GNU Privacy Guard"
#: documents/models.py:138
#: documents/models.py:124
msgid "title"
msgstr "Titel"
#: documents/models.py:151
#: documents/models.py:137
msgid "content"
msgstr "Inhalt"
#: documents/models.py:153
msgid ""
"The raw, text-only data of the document. This field is primarily used for "
"searching."
msgstr ""
"Der Inhalt des Dokuments in Textform. Dieses Feld wird primär für die Suche "
"verwendet."
#: documents/models.py:139
msgid "The raw, text-only data of the document. This field is primarily used for searching."
msgstr "Der Inhalt des Dokuments in Textform. Dieses Feld wird primär für die Suche verwendet."
#: documents/models.py:158
#: documents/models.py:144
msgid "mime type"
msgstr "MIME-Typ"
#: documents/models.py:169
#: documents/models.py:155
msgid "checksum"
msgstr "Prüfsumme"
#: documents/models.py:173
#: documents/models.py:159
msgid "The checksum of the original document."
msgstr "Die Prüfsumme des originalen Dokuments."
#: documents/models.py:177
#: documents/models.py:163
msgid "archive checksum"
msgstr "Archiv-Prüfsumme"
#: documents/models.py:182
#: documents/models.py:168
msgid "The checksum of the archived document."
msgstr "Die Prüfsumme des archivierten Dokuments."
#: documents/models.py:186 documents/models.py:342
#: documents/models.py:172 documents/models.py:328
msgid "created"
msgstr "Ausgestellt"
#: documents/models.py:190
#: documents/models.py:176
msgid "modified"
msgstr "Geändert"
#: documents/models.py:194
#: documents/models.py:180
msgid "storage type"
msgstr "Speichertyp"
#: documents/models.py:202
#: documents/models.py:188
msgid "added"
msgstr "Hinzugefügt"
#: documents/models.py:206
#: documents/models.py:192
msgid "filename"
msgstr "Dateiname"
#: documents/models.py:212
#: documents/models.py:198
msgid "Current filename in storage"
msgstr "Aktueller Dateiname im Datenspeicher"
#: documents/models.py:216
#: documents/models.py:202
msgid "archive filename"
msgstr "Archiv-Dateiname"
#: documents/models.py:222
#: documents/models.py:208
msgid "Current archive filename in storage"
msgstr "Aktueller Dateiname im Archiv"
#: documents/models.py:226
#: documents/models.py:212
msgid "archive serial number"
msgstr "Archiv-Seriennummer"
#: documents/models.py:231
#: documents/models.py:217
msgid "The position of this document in your physical document archive."
msgstr "Die Position dieses Dokuments in Ihrem physischen Dokumentenarchiv."
#: documents/models.py:237
#: documents/models.py:223
msgid "document"
msgstr "Dokument"
#: documents/models.py:238
#: documents/models.py:224
msgid "documents"
msgstr "Dokumente"
#: documents/models.py:325
#: documents/models.py:311
msgid "debug"
msgstr "Debug"
#: documents/models.py:326
#: documents/models.py:312
msgid "information"
msgstr "Information"
#: documents/models.py:327
#: documents/models.py:313
msgid "warning"
msgstr "Warnung"
#: documents/models.py:328
#: documents/models.py:314
msgid "error"
msgstr "Fehler"
#: documents/models.py:329
#: documents/models.py:315
msgid "critical"
msgstr "Kritisch"
#: documents/models.py:333
#: documents/models.py:319
msgid "group"
msgstr "Gruppe"
#: documents/models.py:336
#: documents/models.py:322
msgid "message"
msgstr "Nachricht"
#: documents/models.py:339
#: documents/models.py:325
msgid "level"
msgstr "Level"
#: documents/models.py:346
#: documents/models.py:332
msgid "log"
msgstr "Protokoll"
#: documents/models.py:347
#: documents/models.py:333
msgid "logs"
msgstr "Protokoll"
#: documents/models.py:358 documents/models.py:408
#: documents/models.py:344 documents/models.py:396
msgid "saved view"
msgstr "Gespeicherte Ansicht"
#: documents/models.py:359
#: documents/models.py:345
msgid "saved views"
msgstr "Gespeicherte Ansichten"
#: documents/models.py:362
#: documents/models.py:348
msgid "user"
msgstr "Benutzer"
#: documents/models.py:368
#: documents/models.py:354
msgid "show on dashboard"
msgstr "Auf Startseite zeigen"
#: documents/models.py:371
#: documents/models.py:357
msgid "show in sidebar"
msgstr "In Seitenleiste zeigen"
#: documents/models.py:375
#: documents/models.py:361
msgid "sort field"
msgstr "Sortierfeld"
#: documents/models.py:378
#: documents/models.py:364
msgid "sort reverse"
msgstr "Umgekehrte Sortierung"
#: documents/models.py:384
#: documents/models.py:370
msgid "title contains"
msgstr "Titel enthält"
#: documents/models.py:385
#: documents/models.py:371
msgid "content contains"
msgstr "Inhalt enthält"
#: documents/models.py:386
#: documents/models.py:372
msgid "ASN is"
msgstr "ASN ist"
#: documents/models.py:387
#: documents/models.py:373
msgid "correspondent is"
msgstr "Korrespondent ist"
#: documents/models.py:388
#: documents/models.py:374
msgid "document type is"
msgstr "Dokumenttyp ist"
#: documents/models.py:389
#: documents/models.py:375
msgid "is in inbox"
msgstr "Ist im Posteingang"
#: documents/models.py:390
#: documents/models.py:376
msgid "has tag"
msgstr "Hat Tag"
#: documents/models.py:391
#: documents/models.py:377
msgid "has any tag"
msgstr "Hat irgendein Tag"
#: documents/models.py:392
#: documents/models.py:378
msgid "created before"
msgstr "Ausgestellt vor"
#: documents/models.py:393
#: documents/models.py:379
msgid "created after"
msgstr "Ausgestellt nach"
#: documents/models.py:394
#: documents/models.py:380
msgid "created year is"
msgstr "Ausgestellt im Jahr"
#: documents/models.py:395
#: documents/models.py:381
msgid "created month is"
msgstr "Ausgestellt im Monat"
#: documents/models.py:396
#: documents/models.py:382
msgid "created day is"
msgstr "Ausgestellt am Tag"
#: documents/models.py:397
#: documents/models.py:383
msgid "added before"
msgstr "Hinzugefügt vor"
#: documents/models.py:398
#: documents/models.py:384
msgid "added after"
msgstr "Hinzugefügt nach"
#: documents/models.py:399
#: documents/models.py:385
msgid "modified before"
msgstr "Geändert vor"
#: documents/models.py:400
#: documents/models.py:386
msgid "modified after"
msgstr "Geändert nach"
#: documents/models.py:401
#: documents/models.py:387
msgid "does not have tag"
msgstr "Hat nicht folgendes Tag"
#: documents/models.py:412
#: documents/models.py:388
msgid "does not have ASN"
msgstr "Dokument hat keine ASN"
#: documents/models.py:389
msgid "title or content contains"
msgstr "Titel oder Inhalt enthält"
#: documents/models.py:400
msgid "rule type"
msgstr "Regeltyp"
#: documents/models.py:416
#: documents/models.py:404
msgid "value"
msgstr "Wert"
#: documents/models.py:422
#: documents/models.py:410
msgid "filter rule"
msgstr "Filterregel"
#: documents/models.py:423
#: documents/models.py:411
msgid "filter rules"
msgstr "Filterregeln"
#: documents/serialisers.py:52
#: documents/serialisers.py:53
#, python-format
msgid "Invalid regular expresssion: %(error)s"
msgid "Invalid regular expression: %(error)s"
msgstr "Ungültiger regulärer Ausdruck: %(error)s"
#: documents/serialisers.py:378
#: documents/serialisers.py:177
msgid "Invalid color."
msgstr "Ungültige Farbe."
#: documents/serialisers.py:451
#, python-format
msgid "File type %(type)s not supported"
msgstr "Dateityp %(type)s nicht unterstützt"
#: documents/templates/index.html:20
#: documents/templates/index.html:21
msgid "Paperless-ng is loading..."
msgstr "Paperless-ng wird geladen..."
@@ -390,9 +390,7 @@ msgstr "Bitte melden Sie sich an."
#: documents/templates/registration/login.html:45
msgid "Your username and password didn't match. Please try again."
msgstr ""
"Ihr Benutzername und Passwort stimmen nicht überein. Bitte versuchen Sie es "
"erneut."
msgstr "Ihr Benutzername und Kennwort stimmen nicht überein. Bitte versuchen Sie es erneut."
#: documents/templates/registration/login.html:48
msgid "Username"
@@ -400,36 +398,56 @@ msgstr "Benutzername"
#: documents/templates/registration/login.html:49
msgid "Password"
msgstr "Passwort"
msgstr "Kennwort"
#: documents/templates/registration/login.html:54
msgid "Sign in"
msgstr "Anmelden"
#: paperless/settings.py:291
#: paperless/settings.py:298
msgid "English (US)"
msgstr "Englisch (US)"
#: paperless/settings.py:292
#: paperless/settings.py:299
msgid "English (GB)"
msgstr "Englisch (UK)"
#: paperless/settings.py:293
#: paperless/settings.py:300
msgid "German"
msgstr "Deutsch"
#: paperless/settings.py:294
#: paperless/settings.py:301
msgid "Dutch"
msgstr "Niederländisch"
#: paperless/settings.py:295
#: paperless/settings.py:302
msgid "French"
msgstr "Französisch"
#: paperless/settings.py:296
#: paperless/settings.py:303
msgid "Portuguese (Brazil)"
msgstr "Portugiesisch (Brasilien)"
#: paperless/settings.py:304
msgid "Portuguese"
msgstr "Portugiesisch"
#: paperless/settings.py:305
msgid "Italian"
msgstr "Italienisch"
#: paperless/settings.py:306
msgid "Romanian"
msgstr "Rumänisch"
#: paperless/settings.py:307
msgid "Russian"
msgstr "Russisch"
#: paperless/settings.py:308
msgid "Spanish"
msgstr "Spanisch"
#: paperless/urls.py:118
msgid "Paperless-ng administration"
msgstr "Paperless-ng Administration"
@@ -439,40 +457,24 @@ msgid "Filter"
msgstr "Filter"
#: paperless_mail/admin.py:27
msgid ""
"Paperless will only process mails that match ALL of the filters given below."
msgstr ""
"Paperless wird nur E-Mails verarbeiten, für die alle der hier angegebenen "
"Filter zutreffen."
msgid "Paperless will only process mails that match ALL of the filters given below."
msgstr "Paperless wird nur E-Mails verarbeiten, für die alle der hier angegebenen Filter zutreffen."
#: paperless_mail/admin.py:37
msgid "Actions"
msgstr "Aktionen"
#: paperless_mail/admin.py:39
msgid ""
"The action applied to the mail. This action is only performed when documents"
" were consumed from the mail. Mails without attachments will remain entirely"
" untouched."
msgstr ""
"Die Aktion, die auf E-Mails angewendet werden soll. Diese Aktion wird nur "
"auf E-Mails angewendet, aus denen Anhänge verarbeitet wurden. E-Mails ohne "
"Anhänge werden vollständig ignoriert."
msgid "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched."
msgstr "Die Aktion, die auf E-Mails angewendet werden soll. Diese Aktion wird nur auf E-Mails angewendet, aus denen Anhänge verarbeitet wurden. E-Mails ohne Anhänge werden vollständig ignoriert."
#: paperless_mail/admin.py:46
msgid "Metadata"
msgstr "Metadaten"
#: paperless_mail/admin.py:48
msgid ""
"Assign metadata to documents consumed from this rule automatically. If you "
"do not assign tags, types or correspondents here, paperless will still "
"process all matching rules that you have defined."
msgstr ""
"Folgende Metadaten werden Dokumenten dieser Regel automatisch zugewiesen. "
"Wenn Sie hier nichts auswählen wird Paperless weiterhin alle "
"Zuweisungsalgorithmen ausführen und Metadaten auf Basis des Dokumentinhalts "
"zuweisen."
msgid "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined."
msgstr "Folgende Metadaten werden Dokumenten dieser Regel automatisch zugewiesen. Wenn Sie hier nichts auswählen wird Paperless weiterhin alle Zuweisungsalgorithmen ausführen und Metadaten auf Basis des Dokumentinhalts zuweisen."
#: paperless_mail/apps.py:9
msgid "Paperless mail"
@@ -507,12 +509,8 @@ msgid "IMAP port"
msgstr "IMAP-Port"
#: paperless_mail/models.py:36
msgid ""
"This is usually 143 for unencrypted and STARTTLS connections, and 993 for "
"SSL connections."
msgstr ""
"Dies ist in der Regel 143 für unverschlüsselte und STARTTLS-Verbindungen und"
" 993 für SSL-Verbindungen."
msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections."
msgstr "Dies ist in der Regel 143 für unverschlüsselte und STARTTLS-Verbindungen und 993 für SSL-Verbindungen."
#: paperless_mail/models.py:40
msgid "IMAP security"
@@ -524,7 +522,7 @@ msgstr "Benutzername"
#: paperless_mail/models.py:50
msgid "password"
msgstr "Passwort"
msgstr "Kennwort"
#: paperless_mail/models.py:60
msgid "mail rule"
@@ -611,13 +609,8 @@ msgid "filter attachment filename"
msgstr "Anhang-Dateiname filtern"
#: paperless_mail/models.py:140
msgid ""
"Only consume documents which entirely match this filename if specified. "
"Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr ""
"Wenn angegeben werden nur Dateien verarbeitet, die diesem Dateinamen exakt "
"entsprechen. Platzhalter wie *.pdf oder *rechnung* sind erlaubt. Groß- und "
"Kleinschreibung ist irrelevant."
msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr "Wenn angegeben werden nur Dateien verarbeitet, die diesem Dateinamen exakt entsprechen. Platzhalter wie *.pdf oder *rechnung* sind erlaubt. Groß- und Kleinschreibung ist irrelevant."
#: paperless_mail/models.py:146
msgid "maximum age"
@@ -632,12 +625,8 @@ msgid "attachment type"
msgstr "Dateianhangstyp"
#: paperless_mail/models.py:154
msgid ""
"Inline attachments include embedded images, so it's best to combine this "
"option with a filename filter."
msgstr ""
"'Inline'-Anhänge schließen eingebettete Bilder mit ein, daher sollte diese "
"Einstellung mit einem Dateinamenfilter kombiniert werden."
msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter."
msgstr "'Inline'-Anhänge schließen eingebettete Bilder mit ein, daher sollte diese Einstellung mit einem Dateinamenfilter kombiniert werden."
#: paperless_mail/models.py:159
msgid "action"
@@ -648,12 +637,8 @@ msgid "action parameter"
msgstr "Parameter für Aktion"
#: paperless_mail/models.py:167
msgid ""
"Additional parameter for the action selected above, i.e., the target folder "
"of the move to folder action."
msgstr ""
"Zusätzlicher Parameter für die oben ausgewählte Aktion, zum Beispiel der "
"Zielordner für die Aktion \"In angegebenen Ordner verschieben\""
msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action."
msgstr "Zusätzlicher Parameter für die oben ausgewählte Aktion, zum Beispiel der Zielordner für die Aktion \"In angegebenen Ordner verschieben\"."
#: paperless_mail/models.py:173
msgid "assign title from"
@@ -674,3 +659,4 @@ msgstr "Korrespondent zuweisen von"
#: paperless_mail/models.py:205
msgid "assign this correspondent"
msgstr "Diesen Korrespondent zuweisen"

View File

@@ -1,26 +1,21 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# Ali Bates, 2021
# Jonas Winkler, 2021
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Project-Id-Version: paperless-ng\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-24 16:49+0100\n"
"PO-Revision-Date: 2021-02-16 18:37+0000\n"
"Last-Translator: Jonas Winkler, 2021\n"
"Language-Team: English (United Kingdom) (https://www.transifex.com/paperless/teams/115905/en_GB/)\n"
"POT-Creation-Date: 2021-03-17 22:31+0100\n"
"PO-Revision-Date: 2021-03-17 22:42\n"
"Last-Translator: \n"
"Language-Team: English, United Kingdom\n"
"Language: en_GB\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en_GB\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: paperless-ng\n"
"X-Crowdin-Project-ID: 434940\n"
"X-Crowdin-Language: en-GB\n"
"X-Crowdin-File: /dev/src/locale/en_US/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 54\n"
#: documents/apps.py:10
msgid "Documents"
@@ -50,7 +45,7 @@ msgstr "Fuzzy word"
msgid "Automatic"
msgstr "Automatic"
#: documents/models.py:41 documents/models.py:364 paperless_mail/models.py:25
#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25
#: paperless_mail/models.py:109
msgid "name"
msgstr "name"
@@ -67,7 +62,7 @@ msgstr "matching algorithm"
msgid "is insensitive"
msgstr "is insensitive"
#: documents/models.py:74 documents/models.py:134
#: documents/models.py:74 documents/models.py:120
msgid "correspondent"
msgstr "correspondent"
@@ -75,297 +70,301 @@ msgstr "correspondent"
msgid "correspondents"
msgstr "correspondents"
#: documents/models.py:97
#: documents/models.py:81
msgid "color"
msgstr "colour"
#: documents/models.py:101
#: documents/models.py:87
msgid "is inbox tag"
msgstr "is inbox tag"
#: documents/models.py:103
msgid ""
"Marks this tag as an inbox tag: All newly consumed documents will be tagged "
"with inbox tags."
msgstr ""
"Marks this tag as an inbox tag: All newly consumed documents will be tagged "
"with inbox tags."
#: documents/models.py:89
msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags."
msgstr "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags."
#: documents/models.py:108
#: documents/models.py:94
msgid "tag"
msgstr "tag"
#: documents/models.py:109 documents/models.py:165
#: documents/models.py:95 documents/models.py:151
msgid "tags"
msgstr "tags"
#: documents/models.py:115 documents/models.py:147
#: documents/models.py:101 documents/models.py:133
msgid "document type"
msgstr "document type"
#: documents/models.py:116
#: documents/models.py:102
msgid "document types"
msgstr "document types"
#: documents/models.py:124
#: documents/models.py:110
msgid "Unencrypted"
msgstr "Unencrypted"
#: documents/models.py:125
#: documents/models.py:111
msgid "Encrypted with GNU Privacy Guard"
msgstr "Encrypted with GNU Privacy Guard"
#: documents/models.py:138
#: documents/models.py:124
msgid "title"
msgstr "title"
#: documents/models.py:151
#: documents/models.py:137
msgid "content"
msgstr "content"
#: documents/models.py:153
msgid ""
"The raw, text-only data of the document. This field is primarily used for "
"searching."
msgstr ""
"The raw, text-only data of the document. This field is primarily used for "
"searching."
#: documents/models.py:139
msgid "The raw, text-only data of the document. This field is primarily used for searching."
msgstr "The raw, text-only data of the document. This field is primarily used for searching."
#: documents/models.py:158
#: documents/models.py:144
msgid "mime type"
msgstr "mime type"
#: documents/models.py:169
#: documents/models.py:155
msgid "checksum"
msgstr "checksum"
#: documents/models.py:173
#: documents/models.py:159
msgid "The checksum of the original document."
msgstr "The checksum of the original document."
#: documents/models.py:177
#: documents/models.py:163
msgid "archive checksum"
msgstr "archive checksum"
#: documents/models.py:182
#: documents/models.py:168
msgid "The checksum of the archived document."
msgstr "The checksum of the archived document."
#: documents/models.py:186 documents/models.py:342
#: documents/models.py:172 documents/models.py:328
msgid "created"
msgstr "created"
#: documents/models.py:190
#: documents/models.py:176
msgid "modified"
msgstr "modified"
#: documents/models.py:194
#: documents/models.py:180
msgid "storage type"
msgstr "storage type"
#: documents/models.py:202
#: documents/models.py:188
msgid "added"
msgstr "added"
#: documents/models.py:206
#: documents/models.py:192
msgid "filename"
msgstr "filename"
#: documents/models.py:212
#: documents/models.py:198
msgid "Current filename in storage"
msgstr "Current filename in storage"
#: documents/models.py:216
#: documents/models.py:202
msgid "archive filename"
msgstr "archive filename"
#: documents/models.py:222
#: documents/models.py:208
msgid "Current archive filename in storage"
msgstr "Current archive filename in storage"
#: documents/models.py:226
#: documents/models.py:212
msgid "archive serial number"
msgstr "archive serial number"
#: documents/models.py:231
#: documents/models.py:217
msgid "The position of this document in your physical document archive."
msgstr "The position of this document in your physical document archive."
#: documents/models.py:237
#: documents/models.py:223
msgid "document"
msgstr "document"
#: documents/models.py:238
#: documents/models.py:224
msgid "documents"
msgstr "documents"
#: documents/models.py:325
#: documents/models.py:311
msgid "debug"
msgstr "debug"
#: documents/models.py:326
#: documents/models.py:312
msgid "information"
msgstr "information"
#: documents/models.py:327
#: documents/models.py:313
msgid "warning"
msgstr "warning"
#: documents/models.py:328
#: documents/models.py:314
msgid "error"
msgstr "error"
#: documents/models.py:329
#: documents/models.py:315
msgid "critical"
msgstr "critical"
#: documents/models.py:333
#: documents/models.py:319
msgid "group"
msgstr "group"
#: documents/models.py:336
#: documents/models.py:322
msgid "message"
msgstr "message"
#: documents/models.py:339
#: documents/models.py:325
msgid "level"
msgstr "level"
#: documents/models.py:346
#: documents/models.py:332
msgid "log"
msgstr "log"
#: documents/models.py:347
#: documents/models.py:333
msgid "logs"
msgstr "logs"
#: documents/models.py:358 documents/models.py:408
#: documents/models.py:344 documents/models.py:396
msgid "saved view"
msgstr "saved view"
#: documents/models.py:359
#: documents/models.py:345
msgid "saved views"
msgstr "saved views"
#: documents/models.py:362
#: documents/models.py:348
msgid "user"
msgstr "user"
#: documents/models.py:368
#: documents/models.py:354
msgid "show on dashboard"
msgstr "show on dashboard"
#: documents/models.py:371
#: documents/models.py:357
msgid "show in sidebar"
msgstr "show in sidebar"
#: documents/models.py:375
#: documents/models.py:361
msgid "sort field"
msgstr "sort field"
#: documents/models.py:378
#: documents/models.py:364
msgid "sort reverse"
msgstr "sort reverse"
#: documents/models.py:384
#: documents/models.py:370
msgid "title contains"
msgstr "title contains"
#: documents/models.py:385
#: documents/models.py:371
msgid "content contains"
msgstr "content contains"
#: documents/models.py:386
#: documents/models.py:372
msgid "ASN is"
msgstr "ASN is"
#: documents/models.py:387
#: documents/models.py:373
msgid "correspondent is"
msgstr "correspondent is"
#: documents/models.py:388
#: documents/models.py:374
msgid "document type is"
msgstr "document type is"
#: documents/models.py:389
#: documents/models.py:375
msgid "is in inbox"
msgstr "is in inbox"
#: documents/models.py:390
#: documents/models.py:376
msgid "has tag"
msgstr "has tag"
#: documents/models.py:391
#: documents/models.py:377
msgid "has any tag"
msgstr "has any tag"
#: documents/models.py:392
#: documents/models.py:378
msgid "created before"
msgstr "created before"
#: documents/models.py:393
#: documents/models.py:379
msgid "created after"
msgstr "created after"
#: documents/models.py:394
#: documents/models.py:380
msgid "created year is"
msgstr "created year is"
#: documents/models.py:395
#: documents/models.py:381
msgid "created month is"
msgstr "created month is"
#: documents/models.py:396
#: documents/models.py:382
msgid "created day is"
msgstr "created day is"
#: documents/models.py:397
#: documents/models.py:383
msgid "added before"
msgstr "added before"
#: documents/models.py:398
#: documents/models.py:384
msgid "added after"
msgstr "added after"
#: documents/models.py:399
#: documents/models.py:385
msgid "modified before"
msgstr "modified before"
#: documents/models.py:400
#: documents/models.py:386
msgid "modified after"
msgstr "modified after"
#: documents/models.py:401
#: documents/models.py:387
msgid "does not have tag"
msgstr "does not have tag"
#: documents/models.py:412
#: documents/models.py:388
msgid "does not have ASN"
msgstr "does not have ASN"
#: documents/models.py:389
msgid "title or content contains"
msgstr "title or content contains"
#: documents/models.py:400
msgid "rule type"
msgstr "rule type"
#: documents/models.py:416
#: documents/models.py:404
msgid "value"
msgstr "value"
#: documents/models.py:422
#: documents/models.py:410
msgid "filter rule"
msgstr "filter rule"
#: documents/models.py:423
#: documents/models.py:411
msgid "filter rules"
msgstr "filter rules"
#: documents/serialisers.py:52
#: documents/serialisers.py:53
#, python-format
msgid "Invalid regular expresssion: %(error)s"
msgstr "Invalid regular expresssion: %(error)s"
msgid "Invalid regular expression: %(error)s"
msgstr "Invalid regular expression: %(error)s"
#: documents/serialisers.py:378
#: documents/serialisers.py:177
msgid "Invalid color."
msgstr "Invalid colour."
#: documents/serialisers.py:451
#, python-format
msgid "File type %(type)s not supported"
msgstr "File type %(type)s not supported"
#: documents/templates/index.html:20
#: documents/templates/index.html:21
msgid "Paperless-ng is loading..."
msgstr "Paperless-ng is loading..."
@@ -405,30 +404,50 @@ msgstr "Password"
msgid "Sign in"
msgstr "Sign in"
#: paperless/settings.py:291
#: paperless/settings.py:298
msgid "English (US)"
msgstr "English (US)"
#: paperless/settings.py:292
#: paperless/settings.py:299
msgid "English (GB)"
msgstr "English (GB)"
#: paperless/settings.py:293
#: paperless/settings.py:300
msgid "German"
msgstr "German"
#: paperless/settings.py:294
#: paperless/settings.py:301
msgid "Dutch"
msgstr "Dutch"
#: paperless/settings.py:295
#: paperless/settings.py:302
msgid "French"
msgstr "French"
#: paperless/settings.py:296
#: paperless/settings.py:303
msgid "Portuguese (Brazil)"
msgstr "Portuguese (Brazil)"
#: paperless/settings.py:304
msgid "Portuguese"
msgstr "Portuguese"
#: paperless/settings.py:305
msgid "Italian"
msgstr "Italian"
#: paperless/settings.py:306
msgid "Romanian"
msgstr "Romanian"
#: paperless/settings.py:307
msgid "Russian"
msgstr "Russian"
#: paperless/settings.py:308
msgid "Spanish"
msgstr "Spanish"
#: paperless/urls.py:118
msgid "Paperless-ng administration"
msgstr "Paperless-ng administration"
@@ -438,38 +457,24 @@ msgid "Filter"
msgstr "Filter"
#: paperless_mail/admin.py:27
msgid ""
"Paperless will only process mails that match ALL of the filters given below."
msgstr ""
"Paperless will only process mails that match ALL of the filters given below."
msgid "Paperless will only process mails that match ALL of the filters given below."
msgstr "Paperless will only process mails that match ALL of the filters given below."
#: paperless_mail/admin.py:37
msgid "Actions"
msgstr "Actions"
#: paperless_mail/admin.py:39
msgid ""
"The action applied to the mail. This action is only performed when documents"
" were consumed from the mail. Mails without attachments will remain entirely"
" untouched."
msgstr ""
"The action applied to the mail. This action is only performed when documents"
" were consumed from the mail. Mails without attachments will remain entirely"
" untouched."
msgid "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched."
msgstr "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched."
#: paperless_mail/admin.py:46
msgid "Metadata"
msgstr "Metadata"
#: paperless_mail/admin.py:48
msgid ""
"Assign metadata to documents consumed from this rule automatically. If you "
"do not assign tags, types or correspondents here, paperless will still "
"process all matching rules that you have defined."
msgstr ""
"Assign metadata to documents consumed from this rule automatically. If you "
"do not assign tags, types or correspondents here, paperless will still "
"process all matching rules that you have defined."
msgid "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined."
msgstr "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined."
#: paperless_mail/apps.py:9
msgid "Paperless mail"
@@ -504,12 +509,8 @@ msgid "IMAP port"
msgstr "IMAP port"
#: paperless_mail/models.py:36
msgid ""
"This is usually 143 for unencrypted and STARTTLS connections, and 993 for "
"SSL connections."
msgstr ""
"This is usually 143 for unencrypted and STARTTLS connections, and 993 for "
"SSL connections."
msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections."
msgstr "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections."
#: paperless_mail/models.py:40
msgid "IMAP security"
@@ -608,12 +609,8 @@ msgid "filter attachment filename"
msgstr "filter attachment filename"
#: paperless_mail/models.py:140
msgid ""
"Only consume documents which entirely match this filename if specified. "
"Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr ""
"Only consume documents which entirely match this filename if specified. "
"Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
#: paperless_mail/models.py:146
msgid "maximum age"
@@ -628,12 +625,8 @@ msgid "attachment type"
msgstr "attachment type"
#: paperless_mail/models.py:154
msgid ""
"Inline attachments include embedded images, so it's best to combine this "
"option with a filename filter."
msgstr ""
"Inline attachments include embedded images, so it's best to combine this "
"option with a filename filter."
msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter."
msgstr "Inline attachments include embedded images, so it's best to combine this option with a filename filter."
#: paperless_mail/models.py:159
msgid "action"
@@ -644,12 +637,8 @@ msgid "action parameter"
msgstr "action parameter"
#: paperless_mail/models.py:167
msgid ""
"Additional parameter for the action selected above, i.e., the target folder "
"of the move to folder action."
msgstr ""
"Additional parameter for the action selected above, i.e., the target folder "
"of the move to folder action."
msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action."
msgstr "Additional parameter for the action selected above, i.e., the target folder of the move to folder action."
#: paperless_mail/models.py:173
msgid "assign title from"
@@ -670,3 +659,4 @@ msgstr "assign correspondent from"
#: paperless_mail/models.py:205
msgid "assign this correspondent"
msgstr "assign this correspondent"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-24 16:49+0100\n"
"POT-Creation-Date: 2021-03-17 22:31+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -45,7 +45,7 @@ msgstr ""
msgid "Automatic"
msgstr ""
#: documents/models.py:41 documents/models.py:364 paperless_mail/models.py:25
#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25
#: paperless_mail/models.py:109
msgid "name"
msgstr ""
@@ -62,7 +62,7 @@ msgstr ""
msgid "is insensitive"
msgstr ""
#: documents/models.py:74 documents/models.py:134
#: documents/models.py:74 documents/models.py:120
msgid "correspondent"
msgstr ""
@@ -70,293 +70,305 @@ msgstr ""
msgid "correspondents"
msgstr ""
#: documents/models.py:97
#: documents/models.py:81
msgid "color"
msgstr ""
#: documents/models.py:101
#: documents/models.py:87
msgid "is inbox tag"
msgstr ""
#: documents/models.py:103
#: documents/models.py:89
msgid ""
"Marks this tag as an inbox tag: All newly consumed documents will be tagged "
"with inbox tags."
msgstr ""
#: documents/models.py:108
#: documents/models.py:94
msgid "tag"
msgstr ""
#: documents/models.py:109 documents/models.py:165
#: documents/models.py:95 documents/models.py:151
msgid "tags"
msgstr ""
#: documents/models.py:115 documents/models.py:147
#: documents/models.py:101 documents/models.py:133
msgid "document type"
msgstr ""
#: documents/models.py:116
#: documents/models.py:102
msgid "document types"
msgstr ""
#: documents/models.py:124
#: documents/models.py:110
msgid "Unencrypted"
msgstr ""
#: documents/models.py:125
#: documents/models.py:111
msgid "Encrypted with GNU Privacy Guard"
msgstr ""
#: documents/models.py:138
#: documents/models.py:124
msgid "title"
msgstr ""
#: documents/models.py:151
#: documents/models.py:137
msgid "content"
msgstr ""
#: documents/models.py:153
#: documents/models.py:139
msgid ""
"The raw, text-only data of the document. This field is primarily used for "
"searching."
msgstr ""
#: documents/models.py:158
#: documents/models.py:144
msgid "mime type"
msgstr ""
#: documents/models.py:169
#: documents/models.py:155
msgid "checksum"
msgstr ""
#: documents/models.py:173
#: documents/models.py:159
msgid "The checksum of the original document."
msgstr ""
#: documents/models.py:177
#: documents/models.py:163
msgid "archive checksum"
msgstr ""
#: documents/models.py:182
#: documents/models.py:168
msgid "The checksum of the archived document."
msgstr ""
#: documents/models.py:186 documents/models.py:342
#: documents/models.py:172 documents/models.py:328
msgid "created"
msgstr ""
#: documents/models.py:190
#: documents/models.py:176
msgid "modified"
msgstr ""
#: documents/models.py:194
#: documents/models.py:180
msgid "storage type"
msgstr ""
#: documents/models.py:202
#: documents/models.py:188
msgid "added"
msgstr ""
#: documents/models.py:206
#: documents/models.py:192
msgid "filename"
msgstr ""
#: documents/models.py:212
#: documents/models.py:198
msgid "Current filename in storage"
msgstr ""
#: documents/models.py:216
#: documents/models.py:202
msgid "archive filename"
msgstr ""
#: documents/models.py:222
#: documents/models.py:208
msgid "Current archive filename in storage"
msgstr ""
#: documents/models.py:226
#: documents/models.py:212
msgid "archive serial number"
msgstr ""
#: documents/models.py:231
#: documents/models.py:217
msgid "The position of this document in your physical document archive."
msgstr ""
#: documents/models.py:237
#: documents/models.py:223
msgid "document"
msgstr ""
#: documents/models.py:238
#: documents/models.py:224
msgid "documents"
msgstr ""
#: documents/models.py:325
#: documents/models.py:311
msgid "debug"
msgstr ""
#: documents/models.py:326
#: documents/models.py:312
msgid "information"
msgstr ""
#: documents/models.py:327
#: documents/models.py:313
msgid "warning"
msgstr ""
#: documents/models.py:328
#: documents/models.py:314
msgid "error"
msgstr ""
#: documents/models.py:329
#: documents/models.py:315
msgid "critical"
msgstr ""
#: documents/models.py:333
#: documents/models.py:319
msgid "group"
msgstr ""
#: documents/models.py:336
#: documents/models.py:322
msgid "message"
msgstr ""
#: documents/models.py:339
#: documents/models.py:325
msgid "level"
msgstr ""
#: documents/models.py:346
#: documents/models.py:332
msgid "log"
msgstr ""
#: documents/models.py:347
#: documents/models.py:333
msgid "logs"
msgstr ""
#: documents/models.py:358 documents/models.py:408
#: documents/models.py:344 documents/models.py:396
msgid "saved view"
msgstr ""
#: documents/models.py:359
#: documents/models.py:345
msgid "saved views"
msgstr ""
#: documents/models.py:362
#: documents/models.py:348
msgid "user"
msgstr ""
#: documents/models.py:368
#: documents/models.py:354
msgid "show on dashboard"
msgstr ""
#: documents/models.py:371
#: documents/models.py:357
msgid "show in sidebar"
msgstr ""
#: documents/models.py:375
#: documents/models.py:361
msgid "sort field"
msgstr ""
#: documents/models.py:378
#: documents/models.py:364
msgid "sort reverse"
msgstr ""
#: documents/models.py:384
#: documents/models.py:370
msgid "title contains"
msgstr ""
#: documents/models.py:385
#: documents/models.py:371
msgid "content contains"
msgstr ""
#: documents/models.py:386
#: documents/models.py:372
msgid "ASN is"
msgstr ""
#: documents/models.py:387
#: documents/models.py:373
msgid "correspondent is"
msgstr ""
#: documents/models.py:388
#: documents/models.py:374
msgid "document type is"
msgstr ""
#: documents/models.py:389
#: documents/models.py:375
msgid "is in inbox"
msgstr ""
#: documents/models.py:390
#: documents/models.py:376
msgid "has tag"
msgstr ""
#: documents/models.py:391
#: documents/models.py:377
msgid "has any tag"
msgstr ""
#: documents/models.py:392
#: documents/models.py:378
msgid "created before"
msgstr ""
#: documents/models.py:393
#: documents/models.py:379
msgid "created after"
msgstr ""
#: documents/models.py:394
#: documents/models.py:380
msgid "created year is"
msgstr ""
#: documents/models.py:395
#: documents/models.py:381
msgid "created month is"
msgstr ""
#: documents/models.py:396
#: documents/models.py:382
msgid "created day is"
msgstr ""
#: documents/models.py:397
#: documents/models.py:383
msgid "added before"
msgstr ""
#: documents/models.py:398
#: documents/models.py:384
msgid "added after"
msgstr ""
#: documents/models.py:399
#: documents/models.py:385
msgid "modified before"
msgstr ""
#: documents/models.py:400
#: documents/models.py:386
msgid "modified after"
msgstr ""
#: documents/models.py:401
#: documents/models.py:387
msgid "does not have tag"
msgstr ""
#: documents/models.py:412
#: documents/models.py:388
msgid "does not have ASN"
msgstr ""
#: documents/models.py:389
msgid "title or content contains"
msgstr ""
#: documents/models.py:400
msgid "rule type"
msgstr ""
#: documents/models.py:416
#: documents/models.py:404
msgid "value"
msgstr ""
#: documents/models.py:422
#: documents/models.py:410
msgid "filter rule"
msgstr ""
#: documents/models.py:423
#: documents/models.py:411
msgid "filter rules"
msgstr ""
#: documents/serialisers.py:52
#: documents/serialisers.py:53
#, python-format
msgid "Invalid regular expresssion: %(error)s"
msgid "Invalid regular expression: %(error)s"
msgstr ""
#: documents/serialisers.py:378
#: documents/serialisers.py:177
msgid "Invalid color."
msgstr ""
#: documents/serialisers.py:451
#, python-format
msgid "File type %(type)s not supported"
msgstr ""
#: documents/templates/index.html:20
#: documents/templates/index.html:21
msgid "Paperless-ng is loading..."
msgstr ""
@@ -396,30 +408,50 @@ msgstr ""
msgid "Sign in"
msgstr ""
#: paperless/settings.py:291
#: paperless/settings.py:298
msgid "English (US)"
msgstr ""
#: paperless/settings.py:292
#: paperless/settings.py:299
msgid "English (GB)"
msgstr ""
#: paperless/settings.py:293
#: paperless/settings.py:300
msgid "German"
msgstr ""
#: paperless/settings.py:294
#: paperless/settings.py:301
msgid "Dutch"
msgstr ""
#: paperless/settings.py:295
#: paperless/settings.py:302
msgid "French"
msgstr ""
#: paperless/settings.py:296
#: paperless/settings.py:303
msgid "Portuguese (Brazil)"
msgstr ""
#: paperless/settings.py:304
msgid "Portuguese"
msgstr ""
#: paperless/settings.py:305
msgid "Italian"
msgstr ""
#: paperless/settings.py:306
msgid "Romanian"
msgstr ""
#: paperless/settings.py:307
msgid "Russian"
msgstr ""
#: paperless/settings.py:308
msgid "Spanish"
msgstr ""
#: paperless/urls.py:118
msgid "Paperless-ng administration"
msgstr ""

View File

@@ -0,0 +1,662 @@
msgid ""
msgstr ""
"Project-Id-Version: paperless-ng\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-17 22:31+0100\n"
"PO-Revision-Date: 2021-03-17 21:47\n"
"Last-Translator: \n"
"Language-Team: Spanish\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: paperless-ng\n"
"X-Crowdin-Project-ID: 434940\n"
"X-Crowdin-Language: es-ES\n"
"X-Crowdin-File: /dev/src/locale/en_US/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 54\n"
#: documents/apps.py:10
msgid "Documents"
msgstr "Documentos"
#: documents/models.py:32
msgid "Any word"
msgstr "Cualquier palabra"
#: documents/models.py:33
msgid "All words"
msgstr "Todas las palabras"
#: documents/models.py:34
msgid "Exact match"
msgstr "Coincidencia exacta"
#: documents/models.py:35
msgid "Regular expression"
msgstr "Expresión regular"
#: documents/models.py:36
msgid "Fuzzy word"
msgstr "Palabra borrosa"
#: documents/models.py:37
msgid "Automatic"
msgstr "Automático"
#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25
#: paperless_mail/models.py:109
msgid "name"
msgstr "nombre"
#: documents/models.py:45
msgid "match"
msgstr "coincidencia"
#: documents/models.py:49
msgid "matching algorithm"
msgstr "Algoritmo de coincidencia"
#: documents/models.py:55
msgid "is insensitive"
msgstr "es insensible"
#: documents/models.py:74 documents/models.py:120
msgid "correspondent"
msgstr "Tipo de documento"
#: documents/models.py:75
msgid "correspondents"
msgstr "Tipos de documento"
#: documents/models.py:81
msgid "color"
msgstr "color"
#: documents/models.py:87
msgid "is inbox tag"
msgstr "es etiqueta de bandeja"
#: documents/models.py:89
msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags."
msgstr "Marca esta etiqueta como una etiqueta de bandeja: todos los documentos recién consumidos serán etiquetados con las etiquetas de bandeja."
#: documents/models.py:94
msgid "tag"
msgstr "etiqueta"
#: documents/models.py:95 documents/models.py:151
msgid "tags"
msgstr "etiquetas"
#: documents/models.py:101 documents/models.py:133
msgid "document type"
msgstr "tipo de documento"
#: documents/models.py:102
msgid "document types"
msgstr "tipos de documento"
#: documents/models.py:110
msgid "Unencrypted"
msgstr "Sin encriptar"
#: documents/models.py:111
msgid "Encrypted with GNU Privacy Guard"
msgstr "Encriptado con GNU Privacy Guard"
#: documents/models.py:124
msgid "title"
msgstr "titulo"
#: documents/models.py:137
msgid "content"
msgstr "contenido"
#: documents/models.py:139
msgid "The raw, text-only data of the document. This field is primarily used for searching."
msgstr "Los datos de texto en bruto del documento. Este campo se utiliza principalmente para las búsquedas."
#: documents/models.py:144
msgid "mime type"
msgstr "tipo MIME"
#: documents/models.py:155
msgid "checksum"
msgstr "Cadena de verificación"
#: documents/models.py:159
msgid "The checksum of the original document."
msgstr "La cadena de verificación del documento original."
#: documents/models.py:163
msgid "archive checksum"
msgstr "cadena de comprobación del archivo"
#: documents/models.py:168
msgid "The checksum of the archived document."
msgstr "La cadena de verificación del documento archivado."
#: documents/models.py:172 documents/models.py:328
msgid "created"
msgstr "creado"
#: documents/models.py:176
msgid "modified"
msgstr "modificado"
#: documents/models.py:180
msgid "storage type"
msgstr "tipo de almacenamiento"
#: documents/models.py:188
msgid "added"
msgstr "añadido"
#: documents/models.py:192
msgid "filename"
msgstr "nombre del archivo"
#: documents/models.py:198
msgid "Current filename in storage"
msgstr "Nombre de archivo actual en disco"
#: documents/models.py:202
msgid "archive filename"
msgstr "nombre de archivo"
#: documents/models.py:208
msgid "Current archive filename in storage"
msgstr "Nombre de archivo actual en disco"
#: documents/models.py:212
msgid "archive serial number"
msgstr "número de serie del archivo"
#: documents/models.py:217
msgid "The position of this document in your physical document archive."
msgstr "Posición de este documento en tu archivo físico de documentos."
#: documents/models.py:223
msgid "document"
msgstr "documento"
#: documents/models.py:224
msgid "documents"
msgstr "documentos"
#: documents/models.py:311
msgid "debug"
msgstr "depuración"
#: documents/models.py:312
msgid "information"
msgstr "información"
#: documents/models.py:313
msgid "warning"
msgstr "alerta"
#: documents/models.py:314
msgid "error"
msgstr "error"
#: documents/models.py:315
msgid "critical"
msgstr "crítico"
#: documents/models.py:319
msgid "group"
msgstr "grupo"
#: documents/models.py:322
msgid "message"
msgstr "mensaje"
#: documents/models.py:325
msgid "level"
msgstr "nivel"
#: documents/models.py:332
msgid "log"
msgstr "log"
#: documents/models.py:333
msgid "logs"
msgstr "logs"
#: documents/models.py:344 documents/models.py:396
msgid "saved view"
msgstr "vista guardada"
#: documents/models.py:345
msgid "saved views"
msgstr "vistas guardadas"
#: documents/models.py:348
msgid "user"
msgstr "usuario"
#: documents/models.py:354
msgid "show on dashboard"
msgstr "mostrar en el panel de control"
#: documents/models.py:357
msgid "show in sidebar"
msgstr "mostrar en barra lateral"
#: documents/models.py:361
msgid "sort field"
msgstr "campo de ordenación"
#: documents/models.py:364
msgid "sort reverse"
msgstr "ordenar al revés"
#: documents/models.py:370
msgid "title contains"
msgstr "el titulo contiene"
#: documents/models.py:371
msgid "content contains"
msgstr "el contenido contiene"
#: documents/models.py:372
msgid "ASN is"
msgstr "ASN es"
#: documents/models.py:373
msgid "correspondent is"
msgstr "tipo de documento es"
#: documents/models.py:374
msgid "document type is"
msgstr "el tipo de documento es"
#: documents/models.py:375
msgid "is in inbox"
msgstr "está en la bandeja de entrada"
#: documents/models.py:376
msgid "has tag"
msgstr "tiene la etiqueta"
#: documents/models.py:377
msgid "has any tag"
msgstr "tiene cualquier etiqueta"
#: documents/models.py:378
msgid "created before"
msgstr "creado antes"
#: documents/models.py:379
msgid "created after"
msgstr "creado después"
#: documents/models.py:380
msgid "created year is"
msgstr "el año de creación es"
#: documents/models.py:381
msgid "created month is"
msgstr "el mes de creación es"
#: documents/models.py:382
msgid "created day is"
msgstr "creado el día"
#: documents/models.py:383
msgid "added before"
msgstr "agregado antes de"
#: documents/models.py:384
msgid "added after"
msgstr "agregado después de"
#: documents/models.py:385
msgid "modified before"
msgstr "modificado después de"
#: documents/models.py:386
msgid "modified after"
msgstr "modificado antes de"
#: documents/models.py:387
msgid "does not have tag"
msgstr "no tiene la etiqueta"
#: documents/models.py:388
msgid "does not have ASN"
msgstr "no tiene ASN"
#: documents/models.py:389
msgid "title or content contains"
msgstr "el título o cuerpo contiene"
#: documents/models.py:400
msgid "rule type"
msgstr "tipo de regla"
#: documents/models.py:404
msgid "value"
msgstr "valor"
#: documents/models.py:410
msgid "filter rule"
msgstr "regla de filtrado"
#: documents/models.py:411
msgid "filter rules"
msgstr "reglas de filtrado"
#: documents/serialisers.py:53
#, python-format
msgid "Invalid regular expression: %(error)s"
msgstr "Expresión irregular inválida: %(error)s"
#: documents/serialisers.py:177
msgid "Invalid color."
msgstr "Color inválido."
#: documents/serialisers.py:451
#, python-format
msgid "File type %(type)s not supported"
msgstr "Tipo de fichero %(type)s no suportado"
#: documents/templates/index.html:21
msgid "Paperless-ng is loading..."
msgstr "Paperless-ng está cargándose..."
#: documents/templates/registration/logged_out.html:13
msgid "Paperless-ng signed out"
msgstr "Paperless-ng Sesión cerrada"
#: documents/templates/registration/logged_out.html:41
msgid "You have been successfully logged out. Bye!"
msgstr "Has cerrado la sesión satisfactoriamente. ¡Adiós!"
#: documents/templates/registration/logged_out.html:42
msgid "Sign in again"
msgstr "Iniciar sesión de nuevo"
#: documents/templates/registration/login.html:13
msgid "Paperless-ng sign in"
msgstr "Paperless-ng Iniciar sesión"
#: documents/templates/registration/login.html:42
msgid "Please sign in."
msgstr "Por favor, inicie sesión"
#: documents/templates/registration/login.html:45
msgid "Your username and password didn't match. Please try again."
msgstr "Tu usuario y contraseña no coinciden. Inténtalo de nuevo."
#: documents/templates/registration/login.html:48
msgid "Username"
msgstr "Usuario"
#: documents/templates/registration/login.html:49
msgid "Password"
msgstr "Contraseña"
#: documents/templates/registration/login.html:54
msgid "Sign in"
msgstr "Iniciar sesión"
#: paperless/settings.py:298
msgid "English (US)"
msgstr "Inglés (US)"
#: paperless/settings.py:299
msgid "English (GB)"
msgstr "Inglés (Gran Bretaña)"
#: paperless/settings.py:300
msgid "German"
msgstr "Alemán"
#: paperless/settings.py:301
msgid "Dutch"
msgstr "Alemán"
#: paperless/settings.py:302
msgid "French"
msgstr "Francés"
#: paperless/settings.py:303
msgid "Portuguese (Brazil)"
msgstr "Portugués (Brasil)"
#: paperless/settings.py:304
msgid "Portuguese"
msgstr ""
#: paperless/settings.py:305
msgid "Italian"
msgstr "Italiano"
#: paperless/settings.py:306
msgid "Romanian"
msgstr "Rumano"
#: paperless/settings.py:307
msgid "Russian"
msgstr "Ruso"
#: paperless/settings.py:308
msgid "Spanish"
msgstr "Español"
#: paperless/urls.py:118
msgid "Paperless-ng administration"
msgstr "Paperless-ng Administración"
#: paperless_mail/admin.py:25
msgid "Filter"
msgstr "Filtro"
#: paperless_mail/admin.py:27
msgid "Paperless will only process mails that match ALL of the filters given below."
msgstr "Paperless solo procesará los correos que coincidan con TODOS los filtros escritos abajo."
#: paperless_mail/admin.py:37
msgid "Actions"
msgstr "Acciones"
#: paperless_mail/admin.py:39
msgid "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched."
msgstr "La acción aplicada al correo. Esta acción solo se realiza cuando los documentos se consumen del correo. Los correos sin archivos adjuntos permanecerán totalmente intactos."
#: paperless_mail/admin.py:46
msgid "Metadata"
msgstr "Metadatos"
#: paperless_mail/admin.py:48
msgid "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined."
msgstr "Asignar metadatos a documentos consumidos por esta regla automáticamente. Si no asigna etiquetas, o ipos aquí, paperless procesará igualmente todas las reglas que haya definido."
#: paperless_mail/apps.py:9
msgid "Paperless mail"
msgstr "Correo Paperless"
#: paperless_mail/models.py:11
msgid "mail account"
msgstr "cuenta de correo"
#: paperless_mail/models.py:12
msgid "mail accounts"
msgstr "cuentas de correo"
#: paperless_mail/models.py:19
msgid "No encryption"
msgstr "Sin encriptar"
#: paperless_mail/models.py:20
msgid "Use SSL"
msgstr "Usar SSL"
#: paperless_mail/models.py:21
msgid "Use STARTTLS"
msgstr "Usar STARTTLS"
#: paperless_mail/models.py:29
msgid "IMAP server"
msgstr "Servidor IMAP"
#: paperless_mail/models.py:33
msgid "IMAP port"
msgstr "Puerto IMAP"
#: paperless_mail/models.py:36
msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections."
msgstr "Normalmente 143 para conexiones sin encriptar y STARTTLS, y 993 para conexiones SSL."
#: paperless_mail/models.py:40
msgid "IMAP security"
msgstr "Seguridad IMAP"
#: paperless_mail/models.py:46
msgid "username"
msgstr "usuario"
#: paperless_mail/models.py:50
msgid "password"
msgstr "contraseña"
#: paperless_mail/models.py:60
msgid "mail rule"
msgstr "regla de correo"
#: paperless_mail/models.py:61
msgid "mail rules"
msgstr "reglas de correo"
#: paperless_mail/models.py:67
msgid "Only process attachments."
msgstr "Solo procesar ficheros adjuntos."
#: paperless_mail/models.py:68
msgid "Process all files, including 'inline' attachments."
msgstr "Procesar todos los ficheros, incluyendo ficheros 'incrustados'."
#: paperless_mail/models.py:78
msgid "Mark as read, don't process read mails"
msgstr "Marcar como leído, no procesar archivos leídos"
#: paperless_mail/models.py:79
msgid "Flag the mail, don't process flagged mails"
msgstr "Marcar el correo, no procesar correos marcados"
#: paperless_mail/models.py:80
msgid "Move to specified folder"
msgstr "Mover a carpeta específica"
#: paperless_mail/models.py:81
msgid "Delete"
msgstr "Borrar"
#: paperless_mail/models.py:88
msgid "Use subject as title"
msgstr "Usar asunto como titulo"
#: paperless_mail/models.py:89
msgid "Use attachment filename as title"
msgstr "Usar nombre del fichero adjunto como título"
#: paperless_mail/models.py:99
msgid "Do not assign a correspondent"
msgstr "No asignar un tipo de documento"
#: paperless_mail/models.py:101
msgid "Use mail address"
msgstr "Usar dirección de correo"
#: paperless_mail/models.py:103
msgid "Use name (or mail address if not available)"
msgstr "Usar nombre (o dirección de correo si no está disponible)"
#: paperless_mail/models.py:105
msgid "Use correspondent selected below"
msgstr "Usar el tipo seleccionado debajo"
#: paperless_mail/models.py:113
msgid "order"
msgstr "orden"
#: paperless_mail/models.py:120
msgid "account"
msgstr "cuenta"
#: paperless_mail/models.py:124
msgid "folder"
msgstr "carpeta"
#: paperless_mail/models.py:128
msgid "filter from"
msgstr "filtrar desde"
#: paperless_mail/models.py:131
msgid "filter subject"
msgstr "filtrar asunto"
#: paperless_mail/models.py:134
msgid "filter body"
msgstr "filtrar cuerpo"
#: paperless_mail/models.py:138
msgid "filter attachment filename"
msgstr "filtrar nombre del fichero adjunto"
#: paperless_mail/models.py:140
msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr "Sólo consumirá documentos que coincidan completamente con este nombre de archivo si se especifica. Se permiten comodines como *.pdf o *factura*. No diferencia mayúsculas."
#: paperless_mail/models.py:146
msgid "maximum age"
msgstr "antigüedad máxima"
#: paperless_mail/models.py:148
msgid "Specified in days."
msgstr "Especificado en días."
#: paperless_mail/models.py:151
msgid "attachment type"
msgstr "tipo de fichero adjunto"
#: paperless_mail/models.py:154
msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter."
msgstr "Adjuntos incrustados incluyen imágenes, por lo que es mejor combina resta opción un filtro de nombre de fichero."
#: paperless_mail/models.py:159
msgid "action"
msgstr "acción"
#: paperless_mail/models.py:165
msgid "action parameter"
msgstr "parámetro de acción"
#: paperless_mail/models.py:167
msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action."
msgstr "Parámetro adicional para la acción seleccionada arriba. Ej. la carpeta de destino de la acción de mover a carpeta."
#: paperless_mail/models.py:173
msgid "assign title from"
msgstr "asignar titulo desde"
#: paperless_mail/models.py:183
msgid "assign this tag"
msgstr "asignar esta etiqueta"
#: paperless_mail/models.py:191
msgid "assign this document type"
msgstr "asignar este tipo de documento"
#: paperless_mail/models.py:195
msgid "assign correspondent from"
msgstr "Asignar tipo de documento desde"
#: paperless_mail/models.py:205
msgid "assign this correspondent"
msgstr "asignar este tipo de documento"

View File

@@ -1,26 +1,21 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# Jonas Winkler, 2021
# Philmo67, 2021
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Project-Id-Version: paperless-ng\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-24 16:49+0100\n"
"PO-Revision-Date: 2021-02-16 18:37+0000\n"
"Last-Translator: Philmo67, 2021\n"
"Language-Team: French (https://www.transifex.com/paperless/teams/115905/fr/)\n"
"POT-Creation-Date: 2021-03-17 22:31+0100\n"
"PO-Revision-Date: 2021-03-18 07:48\n"
"Last-Translator: \n"
"Language-Team: French\n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Crowdin-Project: paperless-ng\n"
"X-Crowdin-Project-ID: 434940\n"
"X-Crowdin-Language: fr\n"
"X-Crowdin-File: /dev/src/locale/en_US/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 54\n"
#: documents/apps.py:10
msgid "Documents"
@@ -50,7 +45,7 @@ msgstr "Mot approximatif"
msgid "Automatic"
msgstr "Automatique"
#: documents/models.py:41 documents/models.py:364 paperless_mail/models.py:25
#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25
#: paperless_mail/models.py:109
msgid "name"
msgstr "nom"
@@ -67,7 +62,7 @@ msgstr "algorithme de rapprochement"
msgid "is insensitive"
msgstr "est insensible à la casse"
#: documents/models.py:74 documents/models.py:134
#: documents/models.py:74 documents/models.py:120
msgid "correspondent"
msgstr "correspondant"
@@ -75,298 +70,301 @@ msgstr "correspondant"
msgid "correspondents"
msgstr "correspondants"
#: documents/models.py:97
#: documents/models.py:81
msgid "color"
msgstr "couleur"
#: documents/models.py:101
#: documents/models.py:87
msgid "is inbox tag"
msgstr "est une étiquette de boîte de réception"
#: documents/models.py:103
msgid ""
"Marks this tag as an inbox tag: All newly consumed documents will be tagged "
"with inbox tags."
msgstr ""
"Marque cette étiquette comme étiquette de boîte de réception : ces "
"étiquettes sont affectées à tous les documents nouvellement traités."
#: documents/models.py:89
msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags."
msgstr "Marque cette étiquette comme étiquette de boîte de réception : ces étiquettes sont affectées à tous les documents nouvellement traités."
#: documents/models.py:108
#: documents/models.py:94
msgid "tag"
msgstr "étiquette"
#: documents/models.py:109 documents/models.py:165
#: documents/models.py:95 documents/models.py:151
msgid "tags"
msgstr "étiquettes"
#: documents/models.py:115 documents/models.py:147
#: documents/models.py:101 documents/models.py:133
msgid "document type"
msgstr "type de document"
#: documents/models.py:116
#: documents/models.py:102
msgid "document types"
msgstr "types de document"
#: documents/models.py:124
#: documents/models.py:110
msgid "Unencrypted"
msgstr "Non chiffré"
#: documents/models.py:125
#: documents/models.py:111
msgid "Encrypted with GNU Privacy Guard"
msgstr "Chiffré avec GNU Privacy Guard"
#: documents/models.py:138
#: documents/models.py:124
msgid "title"
msgstr "titre"
#: documents/models.py:151
#: documents/models.py:137
msgid "content"
msgstr "contenu"
#: documents/models.py:153
msgid ""
"The raw, text-only data of the document. This field is primarily used for "
"searching."
msgstr ""
"Les données brutes du document, en format texte uniquement. Ce champ est "
"principalement utilisé pour la recherche."
#: documents/models.py:139
msgid "The raw, text-only data of the document. This field is primarily used for searching."
msgstr "Les données brutes du document, en format texte uniquement. Ce champ est principalement utilisé pour la recherche."
#: documents/models.py:158
#: documents/models.py:144
msgid "mime type"
msgstr "type mime"
#: documents/models.py:169
#: documents/models.py:155
msgid "checksum"
msgstr "somme de contrôle"
#: documents/models.py:173
#: documents/models.py:159
msgid "The checksum of the original document."
msgstr "La somme de contrôle du document original."
#: documents/models.py:177
#: documents/models.py:163
msgid "archive checksum"
msgstr "somme de contrôle de l'archive"
#: documents/models.py:182
#: documents/models.py:168
msgid "The checksum of the archived document."
msgstr "La somme de contrôle du document archivé."
#: documents/models.py:186 documents/models.py:342
#: documents/models.py:172 documents/models.py:328
msgid "created"
msgstr "créé le"
#: documents/models.py:190
#: documents/models.py:176
msgid "modified"
msgstr "modifié"
#: documents/models.py:194
#: documents/models.py:180
msgid "storage type"
msgstr "forme d'enregistrement :"
#: documents/models.py:202
#: documents/models.py:188
msgid "added"
msgstr "date d'ajout"
#: documents/models.py:206
#: documents/models.py:192
msgid "filename"
msgstr "nom du fichier"
#: documents/models.py:212
#: documents/models.py:198
msgid "Current filename in storage"
msgstr "Nom du fichier courant en base de données"
#: documents/models.py:216
#: documents/models.py:202
msgid "archive filename"
msgstr "nom de fichier de l'archive"
#: documents/models.py:222
#: documents/models.py:208
msgid "Current archive filename in storage"
msgstr "Nom du fichier d'archive courant en base de données"
#: documents/models.py:226
#: documents/models.py:212
msgid "archive serial number"
msgstr "numéro de série de l'archive"
#: documents/models.py:231
#: documents/models.py:217
msgid "The position of this document in your physical document archive."
msgstr ""
"Le classement de ce document dans votre archive de documents physiques."
msgstr "Le classement de ce document dans votre archive de documents physiques."
#: documents/models.py:237
#: documents/models.py:223
msgid "document"
msgstr "document"
#: documents/models.py:238
#: documents/models.py:224
msgid "documents"
msgstr "documents"
#: documents/models.py:325
#: documents/models.py:311
msgid "debug"
msgstr "débogage"
#: documents/models.py:326
#: documents/models.py:312
msgid "information"
msgstr "information"
#: documents/models.py:327
#: documents/models.py:313
msgid "warning"
msgstr "avertissement"
#: documents/models.py:328
#: documents/models.py:314
msgid "error"
msgstr "erreur"
#: documents/models.py:329
#: documents/models.py:315
msgid "critical"
msgstr "critique"
#: documents/models.py:333
#: documents/models.py:319
msgid "group"
msgstr "groupe"
#: documents/models.py:336
#: documents/models.py:322
msgid "message"
msgstr "message"
#: documents/models.py:339
#: documents/models.py:325
msgid "level"
msgstr "niveau"
#: documents/models.py:346
#: documents/models.py:332
msgid "log"
msgstr "rapport"
msgstr "journal"
#: documents/models.py:347
#: documents/models.py:333
msgid "logs"
msgstr "rapports"
msgstr "journaux"
#: documents/models.py:358 documents/models.py:408
#: documents/models.py:344 documents/models.py:396
msgid "saved view"
msgstr "vue enregistrée"
#: documents/models.py:359
#: documents/models.py:345
msgid "saved views"
msgstr "vues enregistrées"
#: documents/models.py:362
#: documents/models.py:348
msgid "user"
msgstr "utilisateur"
#: documents/models.py:368
#: documents/models.py:354
msgid "show on dashboard"
msgstr "montrer sur le tableau de bord"
#: documents/models.py:371
#: documents/models.py:357
msgid "show in sidebar"
msgstr "montrer dans la barre latérale"
#: documents/models.py:375
#: documents/models.py:361
msgid "sort field"
msgstr "champ de tri"
#: documents/models.py:378
#: documents/models.py:364
msgid "sort reverse"
msgstr "tri inverse"
#: documents/models.py:384
#: documents/models.py:370
msgid "title contains"
msgstr "le titre contient"
#: documents/models.py:385
#: documents/models.py:371
msgid "content contains"
msgstr "le contenu contient"
#: documents/models.py:386
#: documents/models.py:372
msgid "ASN is"
msgstr "le NSA est"
#: documents/models.py:387
#: documents/models.py:373
msgid "correspondent is"
msgstr "le correspondant est"
#: documents/models.py:388
#: documents/models.py:374
msgid "document type is"
msgstr "le type de document est"
#: documents/models.py:389
#: documents/models.py:375
msgid "is in inbox"
msgstr "est dans la boîte de réception"
#: documents/models.py:390
#: documents/models.py:376
msgid "has tag"
msgstr "porte l'étiquette"
#: documents/models.py:391
#: documents/models.py:377
msgid "has any tag"
msgstr "porte l'une des étiquettes"
#: documents/models.py:392
#: documents/models.py:378
msgid "created before"
msgstr "créé avant"
#: documents/models.py:393
#: documents/models.py:379
msgid "created after"
msgstr "créé après"
#: documents/models.py:394
#: documents/models.py:380
msgid "created year is"
msgstr "l'année de création est"
#: documents/models.py:395
#: documents/models.py:381
msgid "created month is"
msgstr "le mois de création est"
#: documents/models.py:396
#: documents/models.py:382
msgid "created day is"
msgstr "le jour de création est"
#: documents/models.py:397
#: documents/models.py:383
msgid "added before"
msgstr "ajouté avant"
#: documents/models.py:398
#: documents/models.py:384
msgid "added after"
msgstr "ajouté après"
#: documents/models.py:399
#: documents/models.py:385
msgid "modified before"
msgstr "modifié avant"
#: documents/models.py:400
#: documents/models.py:386
msgid "modified after"
msgstr "modifié après"
#: documents/models.py:401
#: documents/models.py:387
msgid "does not have tag"
msgstr "ne porte pas d'étiquette"
#: documents/models.py:412
#: documents/models.py:388
msgid "does not have ASN"
msgstr "ne porte pas de NSA"
#: documents/models.py:389
msgid "title or content contains"
msgstr "le titre ou le contenu contient"
#: documents/models.py:400
msgid "rule type"
msgstr "type de règle"
#: documents/models.py:416
#: documents/models.py:404
msgid "value"
msgstr "valeur"
#: documents/models.py:422
#: documents/models.py:410
msgid "filter rule"
msgstr "règle de filtrage"
#: documents/models.py:423
#: documents/models.py:411
msgid "filter rules"
msgstr "règles de filtrage"
#: documents/serialisers.py:52
#: documents/serialisers.py:53
#, python-format
msgid "Invalid regular expresssion: %(error)s"
msgid "Invalid regular expression: %(error)s"
msgstr "Expression régulière incorrecte : %(error)s"
#: documents/serialisers.py:378
#: documents/serialisers.py:177
msgid "Invalid color."
msgstr "Couleur incorrecte."
#: documents/serialisers.py:451
#, python-format
msgid "File type %(type)s not supported"
msgstr "Type de fichier %(type)s non pris en charge"
#: documents/templates/index.html:20
#: documents/templates/index.html:21
msgid "Paperless-ng is loading..."
msgstr "Paperless-ng est en cours de chargement..."
@@ -392,9 +390,7 @@ msgstr "Veuillez vous connecter."
#: documents/templates/registration/login.html:45
msgid "Your username and password didn't match. Please try again."
msgstr ""
"Votre nom d'utilisateur et votre mot de passe ne correspondent pas. Veuillez"
" réessayer."
msgstr "Votre nom d'utilisateur et votre mot de passe ne correspondent pas. Veuillez réessayer."
#: documents/templates/registration/login.html:48
msgid "Username"
@@ -408,30 +404,50 @@ msgstr "Mot de passe"
msgid "Sign in"
msgstr "S'identifier"
#: paperless/settings.py:291
#: paperless/settings.py:298
msgid "English (US)"
msgstr "Anglais (US)"
#: paperless/settings.py:292
#: paperless/settings.py:299
msgid "English (GB)"
msgstr "Anglais (GB)"
#: paperless/settings.py:293
#: paperless/settings.py:300
msgid "German"
msgstr "Allemand"
#: paperless/settings.py:294
#: paperless/settings.py:301
msgid "Dutch"
msgstr "Néerlandais"
#: paperless/settings.py:295
#: paperless/settings.py:302
msgid "French"
msgstr "Français"
#: paperless/settings.py:296
#: paperless/settings.py:303
msgid "Portuguese (Brazil)"
msgstr "Portugais (Brésil)"
#: paperless/settings.py:304
msgid "Portuguese"
msgstr "Portugais"
#: paperless/settings.py:305
msgid "Italian"
msgstr "Italien"
#: paperless/settings.py:306
msgid "Romanian"
msgstr "Roumain"
#: paperless/settings.py:307
msgid "Russian"
msgstr "Russe"
#: paperless/settings.py:308
msgid "Spanish"
msgstr "Espagnol"
#: paperless/urls.py:118
msgid "Paperless-ng administration"
msgstr "Administration de Paperless-ng"
@@ -441,40 +457,24 @@ msgid "Filter"
msgstr "Filtrage"
#: paperless_mail/admin.py:27
msgid ""
"Paperless will only process mails that match ALL of the filters given below."
msgstr ""
"Paperless-ng ne traitera que les courriers qui correspondent à TOUS les "
"filtres ci-dessous."
msgid "Paperless will only process mails that match ALL of the filters given below."
msgstr "Paperless-ng ne traitera que les courriers qui correspondent à TOUS les filtres ci-dessous."
#: paperless_mail/admin.py:37
msgid "Actions"
msgstr "Actions"
#: paperless_mail/admin.py:39
msgid ""
"The action applied to the mail. This action is only performed when documents"
" were consumed from the mail. Mails without attachments will remain entirely"
" untouched."
msgstr ""
"Action appliquée au courriel. Cette action n'est exécutée que lorsque les "
"documents ont été traités depuis des courriels. Les courriels sans pièces "
"jointes demeurent totalement inchangés."
msgid "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched."
msgstr "Action appliquée au courriel. Cette action n'est exécutée que lorsque les documents ont été traités depuis des courriels. Les courriels sans pièces jointes demeurent totalement inchangés."
#: paperless_mail/admin.py:46
msgid "Metadata"
msgstr "Métadonnées"
#: paperless_mail/admin.py:48
msgid ""
"Assign metadata to documents consumed from this rule automatically. If you "
"do not assign tags, types or correspondents here, paperless will still "
"process all matching rules that you have defined."
msgstr ""
"Affecter automatiquement des métadonnées aux documents traités à partir de "
"cette règle. Si vous n'affectez pas d'étiquette, de type ou de correspondant"
" ici, Paperless-ng appliquera toutes les autres règles de rapprochement que "
"vous avez définies."
msgid "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined."
msgstr "Affecter automatiquement des métadonnées aux documents traités à partir de cette règle. Si vous n'affectez pas d'étiquette, de type ou de correspondant ici, Paperless-ng appliquera toutes les autres règles de rapprochement que vous avez définies."
#: paperless_mail/apps.py:9
msgid "Paperless mail"
@@ -509,12 +509,8 @@ msgid "IMAP port"
msgstr "Port IMAP"
#: paperless_mail/models.py:36
msgid ""
"This is usually 143 for unencrypted and STARTTLS connections, and 993 for "
"SSL connections."
msgstr ""
"Généralement 143 pour les connexions non chiffrées et STARTTLS, et 993 pour "
"les connexions SSL."
msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections."
msgstr "Généralement 143 pour les connexions non chiffrées et STARTTLS, et 993 pour les connexions SSL."
#: paperless_mail/models.py:40
msgid "IMAP security"
@@ -613,13 +609,8 @@ msgid "filter attachment filename"
msgstr "filtrer le nom de fichier de la pièce jointe"
#: paperless_mail/models.py:140
msgid ""
"Only consume documents which entirely match this filename if specified. "
"Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr ""
"Ne traiter que les documents correspondant intégralement à ce nom de fichier"
" s'il est spécifié. Les jokers tels que *.pdf ou *facture* sont autorisés. "
"La casse n'est pas prise en compte."
msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr "Ne traiter que les documents correspondant intégralement à ce nom de fichier s'il est spécifié. Les jokers tels que *.pdf ou *facture* sont autorisés. La casse n'est pas prise en compte."
#: paperless_mail/models.py:146
msgid "maximum age"
@@ -634,12 +625,8 @@ msgid "attachment type"
msgstr "type de pièce jointe"
#: paperless_mail/models.py:154
msgid ""
"Inline attachments include embedded images, so it's best to combine this "
"option with a filename filter."
msgstr ""
"Les pièces jointes en ligne comprennent les images intégrées, il est donc "
"préférable de combiner cette option avec un filtre de nom de fichier."
msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter."
msgstr "Les pièces jointes en ligne comprennent les images intégrées, il est donc préférable de combiner cette option avec un filtre de nom de fichier."
#: paperless_mail/models.py:159
msgid "action"
@@ -650,12 +637,8 @@ msgid "action parameter"
msgstr "paramètre d'action"
#: paperless_mail/models.py:167
msgid ""
"Additional parameter for the action selected above, i.e., the target folder "
"of the move to folder action."
msgstr ""
"Paramètre supplémentaire pour l'action sélectionnée ci-dessus, par exemple "
"le dossier cible de l'action de déplacement vers un dossier."
msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action."
msgstr "Paramètre supplémentaire pour l'action sélectionnée ci-dessus, par exemple le dossier cible de l'action de déplacement vers un dossier."
#: paperless_mail/models.py:173
msgid "assign title from"
@@ -676,3 +659,4 @@ msgstr "affecter le correspondant depuis"
#: paperless_mail/models.py:205
msgid "assign this correspondent"
msgstr "affecter ce correspondant"

View File

@@ -0,0 +1,662 @@
msgid ""
msgstr ""
"Project-Id-Version: paperless-ng\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-17 22:31+0100\n"
"PO-Revision-Date: 2021-03-17 21:47\n"
"Last-Translator: \n"
"Language-Team: Hungarian\n"
"Language: hu_HU\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: paperless-ng\n"
"X-Crowdin-Project-ID: 434940\n"
"X-Crowdin-Language: hu\n"
"X-Crowdin-File: /dev/src/locale/en_US/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 54\n"
#: documents/apps.py:10
msgid "Documents"
msgstr "Dokumentumok"
#: documents/models.py:32
msgid "Any word"
msgstr ""
#: documents/models.py:33
msgid "All words"
msgstr ""
#: documents/models.py:34
msgid "Exact match"
msgstr ""
#: documents/models.py:35
msgid "Regular expression"
msgstr "Regexp"
#: documents/models.py:36
msgid "Fuzzy word"
msgstr ""
#: documents/models.py:37
msgid "Automatic"
msgstr "Automatikus"
#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25
#: paperless_mail/models.py:109
msgid "name"
msgstr ""
#: documents/models.py:45
msgid "match"
msgstr ""
#: documents/models.py:49
msgid "matching algorithm"
msgstr ""
#: documents/models.py:55
msgid "is insensitive"
msgstr ""
#: documents/models.py:74 documents/models.py:120
msgid "correspondent"
msgstr ""
#: documents/models.py:75
msgid "correspondents"
msgstr ""
#: documents/models.py:81
msgid "color"
msgstr ""
#: documents/models.py:87
msgid "is inbox tag"
msgstr ""
#: documents/models.py:89
msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags."
msgstr ""
#: documents/models.py:94
msgid "tag"
msgstr ""
#: documents/models.py:95 documents/models.py:151
msgid "tags"
msgstr ""
#: documents/models.py:101 documents/models.py:133
msgid "document type"
msgstr ""
#: documents/models.py:102
msgid "document types"
msgstr ""
#: documents/models.py:110
msgid "Unencrypted"
msgstr ""
#: documents/models.py:111
msgid "Encrypted with GNU Privacy Guard"
msgstr ""
#: documents/models.py:124
msgid "title"
msgstr ""
#: documents/models.py:137
msgid "content"
msgstr ""
#: documents/models.py:139
msgid "The raw, text-only data of the document. This field is primarily used for searching."
msgstr ""
#: documents/models.py:144
msgid "mime type"
msgstr ""
#: documents/models.py:155
msgid "checksum"
msgstr ""
#: documents/models.py:159
msgid "The checksum of the original document."
msgstr ""
#: documents/models.py:163
msgid "archive checksum"
msgstr ""
#: documents/models.py:168
msgid "The checksum of the archived document."
msgstr ""
#: documents/models.py:172 documents/models.py:328
msgid "created"
msgstr ""
#: documents/models.py:176
msgid "modified"
msgstr ""
#: documents/models.py:180
msgid "storage type"
msgstr ""
#: documents/models.py:188
msgid "added"
msgstr ""
#: documents/models.py:192
msgid "filename"
msgstr ""
#: documents/models.py:198
msgid "Current filename in storage"
msgstr ""
#: documents/models.py:202
msgid "archive filename"
msgstr ""
#: documents/models.py:208
msgid "Current archive filename in storage"
msgstr ""
#: documents/models.py:212
msgid "archive serial number"
msgstr ""
#: documents/models.py:217
msgid "The position of this document in your physical document archive."
msgstr ""
#: documents/models.py:223
msgid "document"
msgstr ""
#: documents/models.py:224
msgid "documents"
msgstr ""
#: documents/models.py:311
msgid "debug"
msgstr ""
#: documents/models.py:312
msgid "information"
msgstr ""
#: documents/models.py:313
msgid "warning"
msgstr ""
#: documents/models.py:314
msgid "error"
msgstr ""
#: documents/models.py:315
msgid "critical"
msgstr ""
#: documents/models.py:319
msgid "group"
msgstr ""
#: documents/models.py:322
msgid "message"
msgstr ""
#: documents/models.py:325
msgid "level"
msgstr ""
#: documents/models.py:332
msgid "log"
msgstr ""
#: documents/models.py:333
msgid "logs"
msgstr ""
#: documents/models.py:344 documents/models.py:396
msgid "saved view"
msgstr ""
#: documents/models.py:345
msgid "saved views"
msgstr ""
#: documents/models.py:348
msgid "user"
msgstr ""
#: documents/models.py:354
msgid "show on dashboard"
msgstr ""
#: documents/models.py:357
msgid "show in sidebar"
msgstr ""
#: documents/models.py:361
msgid "sort field"
msgstr ""
#: documents/models.py:364
msgid "sort reverse"
msgstr ""
#: documents/models.py:370
msgid "title contains"
msgstr ""
#: documents/models.py:371
msgid "content contains"
msgstr ""
#: documents/models.py:372
msgid "ASN is"
msgstr ""
#: documents/models.py:373
msgid "correspondent is"
msgstr ""
#: documents/models.py:374
msgid "document type is"
msgstr ""
#: documents/models.py:375
msgid "is in inbox"
msgstr ""
#: documents/models.py:376
msgid "has tag"
msgstr ""
#: documents/models.py:377
msgid "has any tag"
msgstr ""
#: documents/models.py:378
msgid "created before"
msgstr ""
#: documents/models.py:379
msgid "created after"
msgstr ""
#: documents/models.py:380
msgid "created year is"
msgstr ""
#: documents/models.py:381
msgid "created month is"
msgstr ""
#: documents/models.py:382
msgid "created day is"
msgstr ""
#: documents/models.py:383
msgid "added before"
msgstr ""
#: documents/models.py:384
msgid "added after"
msgstr ""
#: documents/models.py:385
msgid "modified before"
msgstr ""
#: documents/models.py:386
msgid "modified after"
msgstr ""
#: documents/models.py:387
msgid "does not have tag"
msgstr ""
#: documents/models.py:388
msgid "does not have ASN"
msgstr ""
#: documents/models.py:389
msgid "title or content contains"
msgstr ""
#: documents/models.py:400
msgid "rule type"
msgstr ""
#: documents/models.py:404
msgid "value"
msgstr ""
#: documents/models.py:410
msgid "filter rule"
msgstr ""
#: documents/models.py:411
msgid "filter rules"
msgstr ""
#: documents/serialisers.py:53
#, python-format
msgid "Invalid regular expression: %(error)s"
msgstr ""
#: documents/serialisers.py:177
msgid "Invalid color."
msgstr ""
#: documents/serialisers.py:451
#, python-format
msgid "File type %(type)s not supported"
msgstr ""
#: documents/templates/index.html:21
msgid "Paperless-ng is loading..."
msgstr ""
#: documents/templates/registration/logged_out.html:13
msgid "Paperless-ng signed out"
msgstr ""
#: documents/templates/registration/logged_out.html:41
msgid "You have been successfully logged out. Bye!"
msgstr ""
#: documents/templates/registration/logged_out.html:42
msgid "Sign in again"
msgstr ""
#: documents/templates/registration/login.html:13
msgid "Paperless-ng sign in"
msgstr ""
#: documents/templates/registration/login.html:42
msgid "Please sign in."
msgstr ""
#: documents/templates/registration/login.html:45
msgid "Your username and password didn't match. Please try again."
msgstr ""
#: documents/templates/registration/login.html:48
msgid "Username"
msgstr ""
#: documents/templates/registration/login.html:49
msgid "Password"
msgstr ""
#: documents/templates/registration/login.html:54
msgid "Sign in"
msgstr ""
#: paperless/settings.py:298
msgid "English (US)"
msgstr "Angol (US)"
#: paperless/settings.py:299
msgid "English (GB)"
msgstr ""
#: paperless/settings.py:300
msgid "German"
msgstr "Német"
#: paperless/settings.py:301
msgid "Dutch"
msgstr ""
#: paperless/settings.py:302
msgid "French"
msgstr ""
#: paperless/settings.py:303
msgid "Portuguese (Brazil)"
msgstr ""
#: paperless/settings.py:304
msgid "Portuguese"
msgstr ""
#: paperless/settings.py:305
msgid "Italian"
msgstr ""
#: paperless/settings.py:306
msgid "Romanian"
msgstr ""
#: paperless/settings.py:307
msgid "Russian"
msgstr ""
#: paperless/settings.py:308
msgid "Spanish"
msgstr ""
#: paperless/urls.py:118
msgid "Paperless-ng administration"
msgstr ""
#: paperless_mail/admin.py:25
msgid "Filter"
msgstr "Szűrő"
#: paperless_mail/admin.py:27
msgid "Paperless will only process mails that match ALL of the filters given below."
msgstr ""
#: paperless_mail/admin.py:37
msgid "Actions"
msgstr "Műveletek"
#: paperless_mail/admin.py:39
msgid "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched."
msgstr ""
#: paperless_mail/admin.py:46
msgid "Metadata"
msgstr "Metaadat"
#: paperless_mail/admin.py:48
msgid "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined."
msgstr ""
#: paperless_mail/apps.py:9
msgid "Paperless mail"
msgstr ""
#: paperless_mail/models.py:11
msgid "mail account"
msgstr ""
#: paperless_mail/models.py:12
msgid "mail accounts"
msgstr ""
#: paperless_mail/models.py:19
msgid "No encryption"
msgstr ""
#: paperless_mail/models.py:20
msgid "Use SSL"
msgstr ""
#: paperless_mail/models.py:21
msgid "Use STARTTLS"
msgstr ""
#: paperless_mail/models.py:29
msgid "IMAP server"
msgstr ""
#: paperless_mail/models.py:33
msgid "IMAP port"
msgstr ""
#: paperless_mail/models.py:36
msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections."
msgstr ""
#: paperless_mail/models.py:40
msgid "IMAP security"
msgstr ""
#: paperless_mail/models.py:46
msgid "username"
msgstr ""
#: paperless_mail/models.py:50
msgid "password"
msgstr ""
#: paperless_mail/models.py:60
msgid "mail rule"
msgstr ""
#: paperless_mail/models.py:61
msgid "mail rules"
msgstr ""
#: paperless_mail/models.py:67
msgid "Only process attachments."
msgstr ""
#: paperless_mail/models.py:68
msgid "Process all files, including 'inline' attachments."
msgstr ""
#: paperless_mail/models.py:78
msgid "Mark as read, don't process read mails"
msgstr ""
#: paperless_mail/models.py:79
msgid "Flag the mail, don't process flagged mails"
msgstr ""
#: paperless_mail/models.py:80
msgid "Move to specified folder"
msgstr ""
#: paperless_mail/models.py:81
msgid "Delete"
msgstr "Törlés"
#: paperless_mail/models.py:88
msgid "Use subject as title"
msgstr ""
#: paperless_mail/models.py:89
msgid "Use attachment filename as title"
msgstr ""
#: paperless_mail/models.py:99
msgid "Do not assign a correspondent"
msgstr ""
#: paperless_mail/models.py:101
msgid "Use mail address"
msgstr ""
#: paperless_mail/models.py:103
msgid "Use name (or mail address if not available)"
msgstr ""
#: paperless_mail/models.py:105
msgid "Use correspondent selected below"
msgstr ""
#: paperless_mail/models.py:113
msgid "order"
msgstr ""
#: paperless_mail/models.py:120
msgid "account"
msgstr ""
#: paperless_mail/models.py:124
msgid "folder"
msgstr ""
#: paperless_mail/models.py:128
msgid "filter from"
msgstr ""
#: paperless_mail/models.py:131
msgid "filter subject"
msgstr ""
#: paperless_mail/models.py:134
msgid "filter body"
msgstr ""
#: paperless_mail/models.py:138
msgid "filter attachment filename"
msgstr ""
#: paperless_mail/models.py:140
msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr ""
#: paperless_mail/models.py:146
msgid "maximum age"
msgstr ""
#: paperless_mail/models.py:148
msgid "Specified in days."
msgstr ""
#: paperless_mail/models.py:151
msgid "attachment type"
msgstr ""
#: paperless_mail/models.py:154
msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter."
msgstr ""
#: paperless_mail/models.py:159
msgid "action"
msgstr ""
#: paperless_mail/models.py:165
msgid "action parameter"
msgstr ""
#: paperless_mail/models.py:167
msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action."
msgstr ""
#: paperless_mail/models.py:173
msgid "assign title from"
msgstr ""
#: paperless_mail/models.py:183
msgid "assign this tag"
msgstr ""
#: paperless_mail/models.py:191
msgid "assign this document type"
msgstr ""
#: paperless_mail/models.py:195
msgid "assign correspondent from"
msgstr ""
#: paperless_mail/models.py:205
msgid "assign this correspondent"
msgstr ""

Some files were not shown because too many files have changed in this diff Show More