Compare commits

..

17 Commits

Author SHA1 Message Date
Michael Shamoon
7d4ce40a37 v1.9.0 2022-09-26 07:54:10 -07:00
shamoon
8feada6907 Merge pull request #1560 from paperless-ngx/beta
[Beta] Paperless-ngx v1.9.0 Release Candidate
2022-09-26 07:53:16 -07:00
Paperless-ngx Translation Bot [bot]
ed9b0c32d8 New Crowdin updates (#1633)
* bugfix: increase delay

partially reverts 86358d5561
re-implements 4fbabe43ea

Signed-off-by: Florian Brandes <florian.brandes@posteo.de>

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

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

Signed-off-by: Florian Brandes <florian.brandes@posteo.de>
Co-authored-by: Florian Brandes <florian.brandes@posteo.de>
2022-09-26 07:52:44 -07:00
lemmi
27906df149 paperless_cmd.sh: use exec to run supervisord
Without exec, signals aren't passed through properly. Stopping the
container won't have any effect unless killed.

closes #1616
2022-09-20 07:23:04 -07:00
Paperless-ngx Translation Bot [bot]
b8e7f0b45f New Crowdin updates (#1607)
* bugfix: increase delay

partially reverts 86358d5561
re-implements 4fbabe43ea

Signed-off-by: Florian Brandes <florian.brandes@posteo.de>

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

Signed-off-by: Florian Brandes <florian.brandes@posteo.de>
Co-authored-by: Florian Brandes <florian.brandes@posteo.de>
2022-09-16 15:45:17 -07:00
Trenton H
355b3fcb3d Fixes grammar in comment
Co-authored-by: Florian <florian.brandes@posteo.de>
2022-09-16 09:08:16 -07:00
Trenton Holmes
7aa0e5650b Updates how barcodes are detected, using pikepdf images, instead of converting each page to an image 2022-09-16 09:08:16 -07:00
Paperless-ngx Translation Bot [bot]
f9a0adc64e New Crowdin updates (#1580)
* New translations messages.xlf (French)
[ci skip]

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

* New translations messages.xlf (Finnish)
[ci skip]
2022-09-16 08:37:07 -07:00
shamoon
3b34aed64f Merge pull request #1605 from paperless-ngx/fix/1599-consume-permissions
Fix: Consume directory permissions were not updated
2022-09-16 08:31:41 -07:00
Trenton H
3a7cbd3a42 Fixes an issue where the consume directory wasn't included in the permissions fix at Docker entry 2022-09-16 07:52:33 -07:00
Trenton H
0e443ba017 Merge pull request #1596 from paperless-ngx/fix/1590-barcodes
Fix: Double barcode separation creates empty file
2022-09-15 14:18:01 -07:00
shamoon
8ed401aec1 Merge pull request #1591 from paperless-ngx/fix/1583-tika-str
Fix: Parsing Tika documents fails with AttributeError
2022-09-14 21:52:49 -07:00
Trenton Holmes
9ae847039b Fixes the seperation of files by barcode, during the case where 2 barcodes appear back to back 2022-09-14 14:00:37 -07:00
Trenton Holmes
d4cb84ff76 Ensure the tika parse function gets a string, not a PathLike 2022-09-14 07:48:12 -07:00
shamoon
17ae2aacbf Merge pull request #1576 from paperless-ngx/fix/slow-classifier
Fix: Resolve issue with slow classifier
2022-09-13 11:57:58 -07:00
Michael Shamoon
82d03f2dc6 fix tag list vertical space 2022-09-13 11:54:25 -07:00
Trenton Holmes
3cf2aaf8ff Locks numpy version until an upstream fix or resolution to aarch64 classifier slowdown 2022-09-13 10:33:07 -07:00
17 changed files with 607 additions and 530 deletions

View File

@@ -33,6 +33,8 @@ redis = "*"
scikit-learn = "~=1.1" scikit-learn = "~=1.1"
# Pin this until piwheels is building 1.9 (see https://www.piwheels.org/project/scipy/) # Pin this until piwheels is building 1.9 (see https://www.piwheels.org/project/scipy/)
scipy = "==1.8.1" scipy = "==1.8.1"
# https://github.com/paperless-ngx/paperless-ngx/issues/1364
numpy = "==1.22.3"
whitenoise = "~=6.2" whitenoise = "~=6.2"
watchdog = "~=2.1" watchdog = "~=2.1"
whoosh="~=2.7" whoosh="~=2.7"
@@ -51,7 +53,6 @@ concurrent-log-handler = "*"
"importlib-resources" = {version = "*", markers = "python_version < '3.9'"} "importlib-resources" = {version = "*", markers = "python_version < '3.9'"}
zipp = {version = "*", markers = "python_version < '3.9'"} zipp = {version = "*", markers = "python_version < '3.9'"}
pyzbar = "*" pyzbar = "*"
pdf2image = "*"
mysqlclient = "*" mysqlclient = "*"
setproctitle = "*" setproctitle = "*"

50
Pipfile.lock generated
View File

@@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "e187d1abccb2e393ef0fe452737dca7b19aca430117edccfe95160d1902faa21" "sha256": "896665b8ff6d8a99af44b729c581033add1ba5cbd927723ef275649491c92a4f"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": {}, "requires": {},
@@ -712,37 +712,57 @@
}, },
"numpy": { "numpy": {
"hashes": [ "hashes": [
"sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676",
"sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4",
"sha256:17e5226674f6ea79e14e3b91bfbc153fdf3ac13f5cc54ee7bc8fdbe820a32da0", "sha256:17e5226674f6ea79e14e3b91bfbc153fdf3ac13f5cc54ee7bc8fdbe820a32da0",
"sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce",
"sha256:2bd879d3ca4b6f39b7770829f73278b7c5e248c91d538aab1e506c628353e47f", "sha256:2bd879d3ca4b6f39b7770829f73278b7c5e248c91d538aab1e506c628353e47f",
"sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123",
"sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1",
"sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e",
"sha256:4f41f5bf20d9a521f8cab3a34557cd77b6f205ab2116651f12959714494268b0", "sha256:4f41f5bf20d9a521f8cab3a34557cd77b6f205ab2116651f12959714494268b0",
"sha256:5593f67e66dea4e237f5af998d31a43e447786b2154ba1ad833676c788f37cde", "sha256:5593f67e66dea4e237f5af998d31a43e447786b2154ba1ad833676c788f37cde",
"sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5",
"sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d",
"sha256:5e28cd64624dc2354a349152599e55308eb6ca95a13ce6a7d5679ebff2962913", "sha256:5e28cd64624dc2354a349152599e55308eb6ca95a13ce6a7d5679ebff2962913",
"sha256:633679a472934b1c20a12ed0c9a6c9eb167fbb4cb89031939bfd03dd9dbc62b8", "sha256:633679a472934b1c20a12ed0c9a6c9eb167fbb4cb89031939bfd03dd9dbc62b8",
"sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a",
"sha256:806970e69106556d1dd200e26647e9bee5e2b3f1814f9da104a943e8d548ca38", "sha256:806970e69106556d1dd200e26647e9bee5e2b3f1814f9da104a943e8d548ca38",
"sha256:806cc25d5c43e240db709875e947076b2826f47c2c340a5a2f36da5bb10c58d6", "sha256:806cc25d5c43e240db709875e947076b2826f47c2c340a5a2f36da5bb10c58d6",
"sha256:8247f01c4721479e482cc2f9f7d973f3f47810cbc8c65e38fd1bbd3141cc9842", "sha256:8247f01c4721479e482cc2f9f7d973f3f47810cbc8c65e38fd1bbd3141cc9842",
"sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab",
"sha256:8ebf7e194b89bc66b78475bd3624d92980fca4e5bb86dda08d677d786fefc414", "sha256:8ebf7e194b89bc66b78475bd3624d92980fca4e5bb86dda08d677d786fefc414",
"sha256:8ecb818231afe5f0f568c81f12ce50f2b828ff2b27487520d85eb44c71313b9e", "sha256:8ecb818231afe5f0f568c81f12ce50f2b828ff2b27487520d85eb44c71313b9e",
"sha256:8f9d84a24889ebb4c641a9b99e54adb8cab50972f0166a3abc14c3b93163f074", "sha256:8f9d84a24889ebb4c641a9b99e54adb8cab50972f0166a3abc14c3b93163f074",
"sha256:909c56c4d4341ec8315291a105169d8aae732cfb4c250fbc375a1efb7a844f8f", "sha256:909c56c4d4341ec8315291a105169d8aae732cfb4c250fbc375a1efb7a844f8f",
"sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75",
"sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168",
"sha256:9b83d48e464f393d46e8dd8171687394d39bc5abfe2978896b77dc2604e8635d", "sha256:9b83d48e464f393d46e8dd8171687394d39bc5abfe2978896b77dc2604e8635d",
"sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4",
"sha256:ac987b35df8c2a2eab495ee206658117e9ce867acf3ccb376a19e83070e69418", "sha256:ac987b35df8c2a2eab495ee206658117e9ce867acf3ccb376a19e83070e69418",
"sha256:b78d00e48261fbbd04aa0d7427cf78d18401ee0abd89c7559bbf422e5b1c7d01", "sha256:b78d00e48261fbbd04aa0d7427cf78d18401ee0abd89c7559bbf422e5b1c7d01",
"sha256:b8b97a8a87cadcd3f94659b4ef6ec056261fa1e1c3317f4193ac231d4df70215", "sha256:b8b97a8a87cadcd3f94659b4ef6ec056261fa1e1c3317f4193ac231d4df70215",
"sha256:bd5b7ccae24e3d8501ee5563e82febc1771e73bd268eef82a1e8d2b4d556ae66", "sha256:bd5b7ccae24e3d8501ee5563e82febc1771e73bd268eef82a1e8d2b4d556ae66",
"sha256:bdc02c0235b261925102b1bd586579b7158e9d0d07ecb61148a1799214a4afd5", "sha256:bdc02c0235b261925102b1bd586579b7158e9d0d07ecb61148a1799214a4afd5",
"sha256:be6b350dfbc7f708d9d853663772a9310783ea58f6035eec649fb9c4371b5389", "sha256:be6b350dfbc7f708d9d853663772a9310783ea58f6035eec649fb9c4371b5389",
"sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f",
"sha256:c403c81bb8ffb1c993d0165a11493fd4bf1353d258f6997b3ee288b0a48fce77", "sha256:c403c81bb8ffb1c993d0165a11493fd4bf1353d258f6997b3ee288b0a48fce77",
"sha256:cf8c6aed12a935abf2e290860af8e77b26a042eb7f2582ff83dc7ed5f963340c", "sha256:cf8c6aed12a935abf2e290860af8e77b26a042eb7f2582ff83dc7ed5f963340c",
"sha256:d98addfd3c8728ee8b2c49126f3c44c703e2b005d4a95998e2167af176a9e722", "sha256:d98addfd3c8728ee8b2c49126f3c44c703e2b005d4a95998e2167af176a9e722",
"sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18",
"sha256:dc76bca1ca98f4b122114435f83f1fcf3c0fe48e4e6f660e07996abf2f53903c", "sha256:dc76bca1ca98f4b122114435f83f1fcf3c0fe48e4e6f660e07996abf2f53903c",
"sha256:dec198619b7dbd6db58603cd256e092bcadef22a796f778bf87f8592b468441d", "sha256:dec198619b7dbd6db58603cd256e092bcadef22a796f778bf87f8592b468441d",
"sha256:df28dda02c9328e122661f399f7655cdcbcf22ea42daa3650a26bce08a187450", "sha256:df28dda02c9328e122661f399f7655cdcbcf22ea42daa3650a26bce08a187450",
"sha256:e603ca1fb47b913942f3e660a15e55a9ebca906857edfea476ae5f0fe9b457d5", "sha256:e603ca1fb47b913942f3e660a15e55a9ebca906857edfea476ae5f0fe9b457d5",
"sha256:ecfdd68d334a6b97472ed032b5b37a30d8217c097acfff15e8452c710e775524" "sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62",
"sha256:ecfdd68d334a6b97472ed032b5b37a30d8217c097acfff15e8452c710e775524",
"sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe",
"sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430",
"sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802",
"sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa"
], ],
"markers": "python_version >= '3.8'", "index": "pypi",
"version": "==1.23.2" "version": "==1.22.3"
}, },
"ocrmypdf": { "ocrmypdf": {
"hashes": [ "hashes": [
@@ -768,14 +788,6 @@
"index": "pypi", "index": "pypi",
"version": "==2.5.2" "version": "==2.5.2"
}, },
"pdf2image": {
"hashes": [
"sha256:84f79f2b8fad943e36323ea4e937fcb05f26ded0caa0a01181df66049e42fb65",
"sha256:d58ed94d978a70c73c2bb7fdf8acbaf2a7089c29ff8141be5f45433c0c4293bb"
],
"index": "pypi",
"version": "==1.16.0"
},
"pdfminer.six": { "pdfminer.six": {
"hashes": [ "hashes": [
"sha256:5a64c924410ac48501d6060b21638bf401db69f5b1bd57207df7fbc070ac8ae2", "sha256:5a64c924410ac48501d6060b21638bf401db69f5b1bd57207df7fbc070ac8ae2",
@@ -1035,6 +1047,7 @@
}, },
"pyyaml": { "pyyaml": {
"hashes": [ "hashes": [
"sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf",
"sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293",
"sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b",
"sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57",
@@ -1046,26 +1059,32 @@
"sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287",
"sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513",
"sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0",
"sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782",
"sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0",
"sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92",
"sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f",
"sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2",
"sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc",
"sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1",
"sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c",
"sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86",
"sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4",
"sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c",
"sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34",
"sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b",
"sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d",
"sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c",
"sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb",
"sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7",
"sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737",
"sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3",
"sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d",
"sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358",
"sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53",
"sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78",
"sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803",
"sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a",
"sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f",
"sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174",
"sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"
], ],
@@ -2241,6 +2260,7 @@
}, },
"pyyaml": { "pyyaml": {
"hashes": [ "hashes": [
"sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf",
"sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293",
"sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b",
"sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57",
@@ -2252,26 +2272,32 @@
"sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287",
"sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513",
"sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0",
"sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782",
"sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0",
"sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92",
"sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f",
"sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2",
"sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc",
"sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1",
"sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c",
"sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86",
"sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4",
"sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c",
"sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34",
"sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b",
"sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d",
"sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c",
"sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb",
"sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7",
"sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737",
"sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3",
"sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d",
"sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358",
"sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53",
"sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78",
"sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803",
"sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a",
"sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f",
"sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174",
"sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"
], ],

View File

@@ -50,6 +50,7 @@ map_folders() {
# Export these so they can be used in docker-prepare.sh # Export these so they can be used in docker-prepare.sh
export DATA_DIR="${PAPERLESS_DATA_DIR:-/usr/src/paperless/data}" export DATA_DIR="${PAPERLESS_DATA_DIR:-/usr/src/paperless/data}"
export MEDIA_ROOT_DIR="${PAPERLESS_MEDIA_ROOT:-/usr/src/paperless/media}" export MEDIA_ROOT_DIR="${PAPERLESS_MEDIA_ROOT:-/usr/src/paperless/media}"
export CONSUME_DIR="${PAPERLESS_CONSUMPTION_DIR:-/usr/src/paperless/consume}"
} }
initialize() { initialize() {
@@ -77,7 +78,11 @@ initialize() {
local export_dir="/usr/src/paperless/export" local export_dir="/usr/src/paperless/export"
for dir in "${export_dir}" "${DATA_DIR}" "${DATA_DIR}/index" "${MEDIA_ROOT_DIR}" "${MEDIA_ROOT_DIR}/documents" "${MEDIA_ROOT_DIR}/documents/originals" "${MEDIA_ROOT_DIR}/documents/thumbnails"; do for dir in \
"${export_dir}" \
"${DATA_DIR}" "${DATA_DIR}/index" \
"${MEDIA_ROOT_DIR}" "${MEDIA_ROOT_DIR}/documents" "${MEDIA_ROOT_DIR}/documents/originals" "${MEDIA_ROOT_DIR}/documents/thumbnails" \
"${CONSUME_DIR}"; do
if [[ ! -d "${dir}" ]]; then if [[ ! -d "${dir}" ]]; then
echo "Creating directory ${dir}" echo "Creating directory ${dir}"
mkdir "${dir}" mkdir "${dir}"
@@ -91,7 +96,11 @@ initialize() {
set +e set +e
echo "Adjusting permissions of paperless files. This may take a while." echo "Adjusting permissions of paperless files. This may take a while."
chown -R paperless:paperless ${tmp_dir} chown -R paperless:paperless ${tmp_dir}
for dir in "${export_dir}" "${DATA_DIR}" "${MEDIA_ROOT_DIR}"; do for dir in \
"${export_dir}" \
"${DATA_DIR}" \
"${MEDIA_ROOT_DIR}" \
"${CONSUME_DIR}"; do
find "${dir}" -not \( -user paperless -and -group paperless \) -exec chown paperless:paperless {} + find "${dir}" -not \( -user paperless -and -group paperless \) -exec chown paperless:paperless {} +
done done
set -e set -e

View File

@@ -12,4 +12,4 @@ if [ "$(id -u)" == "$(id -u paperless)" ]; then
) )
fi fi
/usr/local/bin/supervisord -c /etc/supervisord.conf "${rootless_args[@]}" exec /usr/local/bin/supervisord -c /etc/supervisord.conf "${rootless_args[@]}"

View File

@@ -80,7 +80,7 @@ a {
} }
.tags { .tags {
top: 0; top: .2rem;
right: 0; right: 0;
max-width: 80%; max-width: 80%;
row-gap: .2rem; row-gap: .2rem;

View File

@@ -5,7 +5,7 @@ export const environment = {
apiBaseUrl: document.baseURI + 'api/', apiBaseUrl: document.baseURI + 'api/',
apiVersion: '2', apiVersion: '2',
appTitle: 'Paperless-ngx', appTitle: 'Paperless-ngx',
version: '1.9.0-rc1', version: '1.9.0',
webSocketHost: window.location.host, webSocketHost: window.location.host,
webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:', webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:',
webSocketBaseUrl: base_url.pathname + 'ws/', webSocketBaseUrl: base_url.pathname + 'ws/',

File diff suppressed because it is too large Load Diff

View File

@@ -345,7 +345,7 @@
<context context-type="sourcefile">src/app/app.component.ts</context> <context context-type="sourcefile">src/app/app.component.ts</context>
<context context-type="linenumber">146</context> <context context-type="linenumber">146</context>
</context-group> </context-group>
<target state="translated">Début de l'envoi …</target> <target state="translated">Début du téléversement...</target>
</trans-unit> </trans-unit>
<trans-unit id="2173456130768795374" datatype="html"> <trans-unit id="2173456130768795374" datatype="html">
<source>Paperless-ngx</source> <source>Paperless-ngx</source>

View File

@@ -1451,7 +1451,7 @@
<context context-type="sourcefile">src/app/components/document-comments/document-comments.component.html</context> <context context-type="sourcefile">src/app/components/document-comments/document-comments.component.html</context>
<context context-type="linenumber">4</context> <context context-type="linenumber">4</context>
</context-group> </context-group>
<target state="needs-translation">Enter comment</target> <target state="translated">Vnesite komentar</target>
</trans-unit> </trans-unit>
<trans-unit id="4025397324401332794" datatype="html"> <trans-unit id="4025397324401332794" datatype="html">
<source> Please enter a comment. </source> <source> Please enter a comment. </source>
@@ -1459,7 +1459,7 @@
<context context-type="sourcefile">src/app/components/document-comments/document-comments.component.html</context> <context context-type="sourcefile">src/app/components/document-comments/document-comments.component.html</context>
<context context-type="linenumber">5,7</context> <context context-type="linenumber">5,7</context>
</context-group> </context-group>
<target state="needs-translation"> Please enter a comment. </target> <target state="translated"> Prosimo, vpišite komentar. </target>
</trans-unit> </trans-unit>
<trans-unit id="2337485514607640701" datatype="html"> <trans-unit id="2337485514607640701" datatype="html">
<source>Add comment</source> <source>Add comment</source>
@@ -1467,7 +1467,7 @@
<context context-type="sourcefile">src/app/components/document-comments/document-comments.component.html</context> <context context-type="sourcefile">src/app/components/document-comments/document-comments.component.html</context>
<context context-type="linenumber">10</context> <context context-type="linenumber">10</context>
</context-group> </context-group>
<target state="needs-translation">Add comment</target> <target state="translated">Dodaj komentar</target>
</trans-unit> </trans-unit>
<trans-unit id="5438997040668245251" datatype="html"> <trans-unit id="5438997040668245251" datatype="html">
<source>Error saving comment: <x id="PH" equiv-text="e.toString()"/></source> <source>Error saving comment: <x id="PH" equiv-text="e.toString()"/></source>
@@ -1475,7 +1475,7 @@
<context context-type="sourcefile">src/app/components/document-comments/document-comments.component.ts</context> <context context-type="sourcefile">src/app/components/document-comments/document-comments.component.ts</context>
<context context-type="linenumber">57</context> <context context-type="linenumber">57</context>
</context-group> </context-group>
<target state="needs-translation">Error saving comment: <x id="PH" equiv-text="e.toString()"/></target> <target state="translated">Napaka pri shranjevanju komentarja: <x id="PH" equiv-text="e.toString()"/></target>
</trans-unit> </trans-unit>
<trans-unit id="7593210124183303626" datatype="html"> <trans-unit id="7593210124183303626" datatype="html">
<source>Error deleting comment: <x id="PH" equiv-text="e.toString()"/></source> <source>Error deleting comment: <x id="PH" equiv-text="e.toString()"/></source>
@@ -1483,7 +1483,7 @@
<context context-type="sourcefile">src/app/components/document-comments/document-comments.component.ts</context> <context context-type="sourcefile">src/app/components/document-comments/document-comments.component.ts</context>
<context context-type="linenumber">72</context> <context context-type="linenumber">72</context>
</context-group> </context-group>
<target state="needs-translation">Error deleting comment: <x id="PH" equiv-text="e.toString()"/></target> <target state="translated">Napaka pri brisanju komentarja: <x id="PH" equiv-text="e.toString()"/></target>
</trans-unit> </trans-unit>
<trans-unit id="1407560924967345762" datatype="html"> <trans-unit id="1407560924967345762" datatype="html">
<source>Page</source> <source>Page</source>
@@ -1859,7 +1859,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">128</context> <context context-type="linenumber">128</context>
</context-group> </context-group>
<target state="needs-translation">Comments</target> <target state="translated">Komentarji</target>
</trans-unit> </trans-unit>
<trans-unit id="3823219296477075982" datatype="html"> <trans-unit id="3823219296477075982" datatype="html">
<source>Discard</source> <source>Discard</source>
@@ -2245,7 +2245,7 @@
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">339</context> <context context-type="linenumber">339</context>
</context-group> </context-group>
<target state="needs-translation">This operation will assign the storage path "<x id="PH" equiv-text="storagePath.name"/>" to <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</target> <target state="translated">Ta operacija bo dodelila pot shranjevanja "<x id="PH" equiv-text="storagePath.name"/>" v <x id="PH_1" equiv-text="this.list.selected.size"/> izbran dokument/e.</target>
</trans-unit> </trans-unit>
<trans-unit id="60728365335056946" datatype="html"> <trans-unit id="60728365335056946" datatype="html">
<source>This operation will remove the storage path from <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</source> <source>This operation will remove the storage path from <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</source>
@@ -2253,7 +2253,7 @@
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">341</context> <context context-type="linenumber">341</context>
</context-group> </context-group>
<target state="needs-translation">This operation will remove the storage path from <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</target> <target state="translated">Ta operacija bo odstranila pot shranjevanja iz <x id="PH" equiv-text="this.list.selected.size"/> izbranih dokumentov.</target>
</trans-unit> </trans-unit>
<trans-unit id="749430623564850405" datatype="html"> <trans-unit id="749430623564850405" datatype="html">
<source>Delete confirm</source> <source>Delete confirm</source>
@@ -2285,7 +2285,7 @@
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">388</context> <context context-type="linenumber">388</context>
</context-group> </context-group>
<target state="needs-translation">This operation will permanently redo OCR for <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</target> <target state="translated">Ta operacija bo trajno obnovila OCR za <x id="PH" equiv-text="this.list.selected.size"/> izbrane dokumente.</target>
</trans-unit> </trans-unit>
<trans-unit id="8076495233090006322" datatype="html"> <trans-unit id="8076495233090006322" datatype="html">
<source>Filter by correspondent</source> <source>Filter by correspondent</source>
@@ -2373,7 +2373,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">180</context> <context context-type="linenumber">180</context>
</context-group> </context-group>
<target state="needs-translation">Filter by document type</target> <target state="translated">Filtriraj po vrsti dokumenta</target>
</trans-unit> </trans-unit>
<trans-unit id="157572966557284263" datatype="html"> <trans-unit id="157572966557284263" datatype="html">
<source>Filter by storage path</source> <source>Filter by storage path</source>
@@ -2385,7 +2385,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">185</context> <context context-type="linenumber">185</context>
</context-group> </context-group>
<target state="needs-translation">Filter by storage path</target> <target state="translated">Filtriraj po poti shrambe</target>
</trans-unit> </trans-unit>
<trans-unit id="3727324658595204357" datatype="html"> <trans-unit id="3727324658595204357" datatype="html">
<source>Created: <x id="INTERPOLATION" equiv-text="{{ document.created | customDate }}"/></source> <source>Created: <x id="INTERPOLATION" equiv-text="{{ document.created | customDate }}"/></source>
@@ -2397,7 +2397,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">48</context> <context context-type="linenumber">48</context>
</context-group> </context-group>
<target state="needs-translation">Created: <x id="INTERPOLATION" equiv-text="{{ document.created | customDate }}"/></target> <target state="translated">Ustvarjeno: <x id="INTERPOLATION" equiv-text="{{ document.created | customDate }}"/></target>
</trans-unit> </trans-unit>
<trans-unit id="2030261243264601523" datatype="html"> <trans-unit id="2030261243264601523" datatype="html">
<source>Added: <x id="INTERPOLATION" equiv-text="{{ document.added | customDate }}"/></source> <source>Added: <x id="INTERPOLATION" equiv-text="{{ document.added | customDate }}"/></source>
@@ -2409,7 +2409,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">49</context> <context context-type="linenumber">49</context>
</context-group> </context-group>
<target state="needs-translation">Added: <x id="INTERPOLATION" equiv-text="{{ document.added | customDate }}"/></target> <target state="translated">Dodano: <x id="INTERPOLATION" equiv-text="{{ document.added | customDate }}"/></target>
</trans-unit> </trans-unit>
<trans-unit id="4235671847487610290" datatype="html"> <trans-unit id="4235671847487610290" datatype="html">
<source>Modified: <x id="INTERPOLATION" equiv-text="{{ document.modified | customDate }}"/></source> <source>Modified: <x id="INTERPOLATION" equiv-text="{{ document.modified | customDate }}"/></source>
@@ -2421,7 +2421,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">50</context> <context context-type="linenumber">50</context>
</context-group> </context-group>
<target state="needs-translation">Modified: <x id="INTERPOLATION" equiv-text="{{ document.modified | customDate }}"/></target> <target state="translated">Spremenjeno: <x id="INTERPOLATION" equiv-text="{{ document.modified | customDate }}"/></target>
</trans-unit> </trans-unit>
<trans-unit id="2332107018974972998" datatype="html"> <trans-unit id="2332107018974972998" datatype="html">
<source>Score:</source> <source>Score:</source>
@@ -2437,7 +2437,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">14</context> <context context-type="linenumber">14</context>
</context-group> </context-group>
<target state="needs-translation">Toggle tag filter</target> <target state="translated">Preklopi filter oznak</target>
</trans-unit> </trans-unit>
<trans-unit id="4648526799630820486" datatype="html"> <trans-unit id="4648526799630820486" datatype="html">
<source>Toggle correspondent filter</source> <source>Toggle correspondent filter</source>
@@ -2445,7 +2445,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">24</context> <context context-type="linenumber">24</context>
</context-group> </context-group>
<target state="needs-translation">Toggle correspondent filter</target> <target state="translated">Preklop korespondenčnega filtra</target>
</trans-unit> </trans-unit>
<trans-unit id="5319701482646590642" datatype="html"> <trans-unit id="5319701482646590642" datatype="html">
<source>Toggle document type filter</source> <source>Toggle document type filter</source>
@@ -2453,7 +2453,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">31</context> <context context-type="linenumber">31</context>
</context-group> </context-group>
<target state="needs-translation">Toggle document type filter</target> <target state="translated">Preklop filtra vrste dokumenta</target>
</trans-unit> </trans-unit>
<trans-unit id="8950368321707344185" datatype="html"> <trans-unit id="8950368321707344185" datatype="html">
<source>Toggle storage path filter</source> <source>Toggle storage path filter</source>
@@ -2461,7 +2461,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">38</context> <context context-type="linenumber">38</context>
</context-group> </context-group>
<target state="needs-translation">Toggle storage path filter</target> <target state="translated">Preklop filtra poti za shranjevanje</target>
</trans-unit> </trans-unit>
<trans-unit id="5145213156408463657" datatype="html"> <trans-unit id="5145213156408463657" datatype="html">
<source>Select none</source> <source>Select none</source>
@@ -2589,7 +2589,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">175</context>
</context-group> </context-group>
<target state="needs-translation">Edit document</target> <target state="translated">Uredi dokument</target>
</trans-unit> </trans-unit>
<trans-unit id="2155249406916744630" datatype="html"> <trans-unit id="2155249406916744630" datatype="html">
<source>View &quot;<x id="PH" equiv-text="this.list.activeSavedViewTitle"/>&quot; saved successfully.</source> <source>View &quot;<x id="PH" equiv-text="this.list.activeSavedViewTitle"/>&quot; saved successfully.</source>
@@ -2709,7 +2709,7 @@
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">164</context> <context context-type="linenumber">164</context>
</context-group> </context-group>
<target state="needs-translation">equals</target> <target state="translated">je enako</target>
</trans-unit> </trans-unit>
<trans-unit id="5325481293405718739" datatype="html"> <trans-unit id="5325481293405718739" datatype="html">
<source>is empty</source> <source>is empty</source>
@@ -2717,7 +2717,7 @@
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">168</context> <context context-type="linenumber">168</context>
</context-group> </context-group>
<target state="needs-translation">is empty</target> <target state="translated">je prazno</target>
</trans-unit> </trans-unit>
<trans-unit id="6166785695326182482" datatype="html"> <trans-unit id="6166785695326182482" datatype="html">
<source>is not empty</source> <source>is not empty</source>
@@ -2725,7 +2725,7 @@
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">172</context> <context context-type="linenumber">172</context>
</context-group> </context-group>
<target state="needs-translation">is not empty</target> <target state="translated">ni prazno</target>
</trans-unit> </trans-unit>
<trans-unit id="4686622206659266699" datatype="html"> <trans-unit id="4686622206659266699" datatype="html">
<source>greater than</source> <source>greater than</source>
@@ -2733,7 +2733,7 @@
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">176</context> <context context-type="linenumber">176</context>
</context-group> </context-group>
<target state="needs-translation">greater than</target> <target state="translated">večje kot</target>
</trans-unit> </trans-unit>
<trans-unit id="8014012170270529279" datatype="html"> <trans-unit id="8014012170270529279" datatype="html">
<source>less than</source> <source>less than</source>
@@ -2741,7 +2741,7 @@
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">180</context> <context context-type="linenumber">180</context>
</context-group> </context-group>
<target state="needs-translation">less than</target> <target state="translated">manj kot</target>
</trans-unit> </trans-unit>
<trans-unit id="7210076240260527720" datatype="html"> <trans-unit id="7210076240260527720" datatype="html">
<source>Save current view</source> <source>Save current view</source>
@@ -2805,7 +2805,7 @@
<context context-type="sourcefile">src/app/components/manage/correspondent-list/correspondent-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/correspondent-list/correspondent-list.component.ts</context>
<context context-type="linenumber">34</context> <context context-type="linenumber">34</context>
</context-group> </context-group>
<target state="needs-translation">correspondents</target> <target state="translated">dopisniki</target>
</trans-unit> </trans-unit>
<trans-unit id="6360600151505327572" datatype="html"> <trans-unit id="6360600151505327572" datatype="html">
<source>Last used</source> <source>Last used</source>
@@ -2837,7 +2837,7 @@
<context context-type="sourcefile">src/app/components/manage/document-type-list/document-type-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/document-type-list/document-type-list.component.ts</context>
<context context-type="linenumber">31</context> <context context-type="linenumber">31</context>
</context-group> </context-group>
<target state="needs-translation">document types</target> <target state="translated">vrste dokumentov</target>
</trans-unit> </trans-unit>
<trans-unit id="4990731724078522539" datatype="html"> <trans-unit id="4990731724078522539" datatype="html">
<source>Do you really want to delete the document type &quot;<x id="PH" equiv-text="object.name"/>&quot;?</source> <source>Do you really want to delete the document type &quot;<x id="PH" equiv-text="object.name"/>&quot;?</source>
@@ -2965,7 +2965,7 @@
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context> <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context>
<context context-type="linenumber">74</context> <context context-type="linenumber">74</context>
</context-group> </context-group>
<target state="needs-translation">{VAR_PLURAL, plural, =1 {One <x id="INTERPOLATION"/>} other {<x id="INTERPOLATION_1"/> total <x id="INTERPOLATION_2"/>}}</target> <target state="translated">{VAR_PLURAL, plural, =1 {Eden <x id="INTERPOLATION"/>} other {<x id="INTERPOLATION_1"/> skupno <x id="INTERPOLATION_2"/>}}</target>
</trans-unit> </trans-unit>
<trans-unit id="810888510148304696" datatype="html"> <trans-unit id="810888510148304696" datatype="html">
<source>Automatic</source> <source>Automatic</source>
@@ -2985,7 +2985,7 @@
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
<context context-type="linenumber">140</context> <context context-type="linenumber">140</context>
</context-group> </context-group>
<target state="needs-translation">Do you really want to delete the <x id="PH" equiv-text="this.typeName"/>?</target> <target state="translated">Ali res želite izbrisati <x id="PH" equiv-text="this.typeName"/>?</target>
</trans-unit> </trans-unit>
<trans-unit id="8371896857609524947" datatype="html"> <trans-unit id="8371896857609524947" datatype="html">
<source>Associated documents will not be deleted.</source> <source>Associated documents will not be deleted.</source>
@@ -3001,7 +3001,7 @@
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
<context context-type="linenumber">168,170</context> <context context-type="linenumber">168,170</context>
</context-group> </context-group>
<target state="needs-translation">Error while deleting element: <x id="PH" equiv-text="JSON.stringify( error.error )"/></target> <target state="translated">Napaka pri brisanju elementa: <x id="PH" equiv-text="JSON.stringify( error.error )"/></target>
</trans-unit> </trans-unit>
<trans-unit id="6439365426343089851" datatype="html"> <trans-unit id="6439365426343089851" datatype="html">
<source>General</source> <source>General</source>
@@ -3009,7 +3009,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">10</context> <context context-type="linenumber">10</context>
</context-group> </context-group>
<target state="needs-translation">General</target> <target state="translated">Splošno</target>
</trans-unit> </trans-unit>
<trans-unit id="8671234314555525900" datatype="html"> <trans-unit id="8671234314555525900" datatype="html">
<source>Appearance</source> <source>Appearance</source>
@@ -3145,7 +3145,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">105</context> <context context-type="linenumber">105</context>
</context-group> </context-group>
<target state="needs-translation">Theme Color</target> <target state="translated">Barve teme</target>
</trans-unit> </trans-unit>
<trans-unit id="7808756054397155068" datatype="html"> <trans-unit id="7808756054397155068" datatype="html">
<source>Reset</source> <source>Reset</source>
@@ -3153,7 +3153,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">114</context> <context context-type="linenumber">114</context>
</context-group> </context-group>
<target state="needs-translation">Reset</target> <target state="translated">Ponastavi</target>
</trans-unit> </trans-unit>
<trans-unit id="8508424367627989968" datatype="html"> <trans-unit id="8508424367627989968" datatype="html">
<source>Bulk editing</source> <source>Bulk editing</source>
@@ -3193,7 +3193,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">132</context> <context context-type="linenumber">132</context>
</context-group> </context-group>
<target state="needs-translation">Enable comments</target> <target state="translated">Omogoči komentarje</target>
</trans-unit> </trans-unit>
<trans-unit id="5851560788527570644" datatype="html"> <trans-unit id="5851560788527570644" datatype="html">
<source>Notifications</source> <source>Notifications</source>
@@ -3281,7 +3281,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">253</context> <context context-type="linenumber">253</context>
</context-group> </context-group>
<target state="needs-translation">Settings saved</target> <target state="translated">Nastavitve shranjene</target>
</trans-unit> </trans-unit>
<trans-unit id="7217000812750597833" datatype="html"> <trans-unit id="7217000812750597833" datatype="html">
<source>Settings were saved successfully.</source> <source>Settings were saved successfully.</source>
@@ -3289,7 +3289,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">254</context> <context context-type="linenumber">254</context>
</context-group> </context-group>
<target state="needs-translation">Settings were saved successfully.</target> <target state="translated">Nastavitve uspešno shranjene.</target>
</trans-unit> </trans-unit>
<trans-unit id="525012668859298131" datatype="html"> <trans-unit id="525012668859298131" datatype="html">
<source>Settings were saved successfully. Reload is required to apply some changes.</source> <source>Settings were saved successfully. Reload is required to apply some changes.</source>
@@ -3297,7 +3297,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">258</context> <context context-type="linenumber">258</context>
</context-group> </context-group>
<target state="needs-translation">Settings were saved successfully. Reload is required to apply some changes.</target> <target state="translated">Nastavitve so bile uspešno shranjene. Za uveljavitev nekaterih sprememb je potreben ponovni zagon.</target>
</trans-unit> </trans-unit>
<trans-unit id="8491974984518503778" datatype="html"> <trans-unit id="8491974984518503778" datatype="html">
<source>Reload now</source> <source>Reload now</source>
@@ -3305,7 +3305,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">259</context> <context context-type="linenumber">259</context>
</context-group> </context-group>
<target state="needs-translation">Reload now</target> <target state="translated">Ponovno zaženi</target>
</trans-unit> </trans-unit>
<trans-unit id="3011185103048412841" datatype="html"> <trans-unit id="3011185103048412841" datatype="html">
<source>An error occurred while saving settings.</source> <source>An error occurred while saving settings.</source>
@@ -3313,7 +3313,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">269</context> <context context-type="linenumber">269</context>
</context-group> </context-group>
<target state="needs-translation">An error occurred while saving settings.</target> <target state="translated">Prišlo je do napake ob shranjevanju nastavitev.</target>
</trans-unit> </trans-unit>
<trans-unit id="6839066544204061364" datatype="html"> <trans-unit id="6839066544204061364" datatype="html">
<source>Use system language</source> <source>Use system language</source>
@@ -3337,7 +3337,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">304,306</context> <context context-type="linenumber">304,306</context>
</context-group> </context-group>
<target state="needs-translation">Error while storing settings on server: <x id="PH" equiv-text="JSON.stringify( error.error )"/></target> <target state="translated">Napaka pri shranjevanju nastavitev na strežnik: <x id="PH" equiv-text="JSON.stringify( error.error )"/></target>
</trans-unit> </trans-unit>
<trans-unit id="5101757640976222639" datatype="html"> <trans-unit id="5101757640976222639" datatype="html">
<source>storage path</source> <source>storage path</source>
@@ -3345,7 +3345,7 @@
<context context-type="sourcefile">src/app/components/manage/storage-path-list/storage-path-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/storage-path-list/storage-path-list.component.ts</context>
<context context-type="linenumber">30</context> <context context-type="linenumber">30</context>
</context-group> </context-group>
<target state="needs-translation">storage path</target> <target state="translated">pot do shrambe</target>
</trans-unit> </trans-unit>
<trans-unit id="22235115124223314" datatype="html"> <trans-unit id="22235115124223314" datatype="html">
<source>storage paths</source> <source>storage paths</source>
@@ -3353,7 +3353,7 @@
<context context-type="sourcefile">src/app/components/manage/storage-path-list/storage-path-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/storage-path-list/storage-path-list.component.ts</context>
<context context-type="linenumber">31</context> <context context-type="linenumber">31</context>
</context-group> </context-group>
<target state="needs-translation">storage paths</target> <target state="translated">poti do shrambe</target>
</trans-unit> </trans-unit>
<trans-unit id="1569070683025071137" datatype="html"> <trans-unit id="1569070683025071137" datatype="html">
<source>Do you really want to delete the storage path &quot;<x id="PH" equiv-text="object.name"/>&quot;?</source> <source>Do you really want to delete the storage path &quot;<x id="PH" equiv-text="object.name"/>&quot;?</source>
@@ -3361,7 +3361,7 @@
<context context-type="sourcefile">src/app/components/manage/storage-path-list/storage-path-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/storage-path-list/storage-path-list.component.ts</context>
<context context-type="linenumber">45</context> <context context-type="linenumber">45</context>
</context-group> </context-group>
<target state="needs-translation">Do you really want to delete the storage path "<x id="PH" equiv-text="object.name"/>"?</target> <target state="translated">Ali res želite izbrisati pot shranjevanja "<x id="PH" equiv-text="object.name"/>"?</target>
</trans-unit> </trans-unit>
<trans-unit id="6402703264596649214" datatype="html"> <trans-unit id="6402703264596649214" datatype="html">
<source>tag</source> <source>tag</source>
@@ -3369,7 +3369,7 @@
<context context-type="sourcefile">src/app/components/manage/tag-list/tag-list.component.ts</context> <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">30</context>
</context-group> </context-group>
<target state="needs-translation">tag</target> <target state="translated">oznaka</target>
</trans-unit> </trans-unit>
<trans-unit id="4975748273657042999" datatype="html"> <trans-unit id="4975748273657042999" datatype="html">
<source>tags</source> <source>tags</source>
@@ -3377,7 +3377,7 @@
<context context-type="sourcefile">src/app/components/manage/tag-list/tag-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/tag-list/tag-list.component.ts</context>
<context context-type="linenumber">31</context> <context context-type="linenumber">31</context>
</context-group> </context-group>
<target state="needs-translation">tags</target> <target state="translated">oznake</target>
</trans-unit> </trans-unit>
<trans-unit id="93754014749412887" datatype="html"> <trans-unit id="93754014749412887" datatype="html">
<source>Do you really want to delete the tag &quot;<x id="PH" equiv-text="object.name"/>&quot;?</source> <source>Do you really want to delete the tag &quot;<x id="PH" equiv-text="object.name"/>&quot;?</source>
@@ -3393,7 +3393,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">1</context> <context context-type="linenumber">1</context>
</context-group> </context-group>
<target state="needs-translation">File Tasks</target> <target state="translated">Datotečne naloge</target>
</trans-unit> </trans-unit>
<trans-unit id="103921551219467537" datatype="html"> <trans-unit id="103921551219467537" datatype="html">
<source>Clear selection</source> <source>Clear selection</source>
@@ -3401,7 +3401,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">6</context> <context context-type="linenumber">6</context>
</context-group> </context-group>
<target state="needs-translation">Clear selection</target> <target state="translated">Počisti izbiro</target>
</trans-unit> </trans-unit>
<trans-unit id="187187500641108332" datatype="html"> <trans-unit id="187187500641108332" datatype="html">
<source> <source>
@@ -3411,7 +3411,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">11</context> <context context-type="linenumber">11</context>
</context-group> </context-group>
<target state="needs-translation"><x id="INTERPOLATION" equiv-text="{{dismissButtonText}}"/></target> <target state="translated"><x id="INTERPOLATION" equiv-text="{{dismissButtonText}}"/></target>
</trans-unit> </trans-unit>
<trans-unit id="1102717806459547726" datatype="html"> <trans-unit id="1102717806459547726" datatype="html">
<source>Refresh</source> <source>Refresh</source>
@@ -3419,7 +3419,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">20</context> <context context-type="linenumber">20</context>
</context-group> </context-group>
<target state="needs-translation">Refresh</target> <target state="translated">Osveži</target>
</trans-unit> </trans-unit>
<trans-unit id="5968132631442328843" datatype="html"> <trans-unit id="5968132631442328843" datatype="html">
<source>Results</source> <source>Results</source>
@@ -3427,7 +3427,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">42</context> <context context-type="linenumber">42</context>
</context-group> </context-group>
<target state="needs-translation">Results</target> <target state="translated">Rezultat</target>
</trans-unit> </trans-unit>
<trans-unit id="8958063833276423847" datatype="html"> <trans-unit id="8958063833276423847" datatype="html">
<source>click for full output</source> <source>click for full output</source>
@@ -3435,7 +3435,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">66</context> <context context-type="linenumber">66</context>
</context-group> </context-group>
<target state="needs-translation">click for full output</target> <target state="translated">kliknite za celoten izpis</target>
</trans-unit> </trans-unit>
<trans-unit id="1536087519743707362" datatype="html"> <trans-unit id="1536087519743707362" datatype="html">
<source>Dismiss</source> <source>Dismiss</source>
@@ -3447,7 +3447,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context>
<context context-type="linenumber">54</context> <context context-type="linenumber">54</context>
</context-group> </context-group>
<target state="needs-translation">Dismiss</target> <target state="translated">Opusti</target>
</trans-unit> </trans-unit>
<trans-unit id="6798650225457993016" datatype="html"> <trans-unit id="6798650225457993016" datatype="html">
<source>Failed <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.failedFileTasks.length &gt; 0&quot; class=&quot;badge bg-danger ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.failedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source> <source>Failed <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.failedFileTasks.length &gt; 0&quot; class=&quot;badge bg-danger ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.failedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
@@ -3455,7 +3455,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">96</context> <context context-type="linenumber">96</context>
</context-group> </context-group>
<target state="needs-translation">Failed <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.failedFileTasks.length &gt; 0&quot; class=&quot;badge bg-danger ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.failedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target> <target state="translated">Neuspešno <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.failedFileTasks.length &gt; 0&quot; class=&quot;badge bg-danger ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.failedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
</trans-unit> </trans-unit>
<trans-unit id="2352193508676933865" datatype="html"> <trans-unit id="2352193508676933865" datatype="html">
<source>Complete <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.completedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.completedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source> <source>Complete <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.completedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.completedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
@@ -3463,7 +3463,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">102</context> <context context-type="linenumber">102</context>
</context-group> </context-group>
<target state="needs-translation">Complete <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.completedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.completedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target> <target state="translated">Dokončano <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.completedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.completedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
</trans-unit> </trans-unit>
<trans-unit id="1697296301417588213" datatype="html"> <trans-unit id="1697296301417588213" datatype="html">
<source>Started <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.startedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.startedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source> <source>Started <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.startedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.startedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
@@ -3471,7 +3471,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">108</context> <context context-type="linenumber">108</context>
</context-group> </context-group>
<target state="needs-translation">Started <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.startedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.startedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target> <target state="translated">Začetek <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.startedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.startedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
</trans-unit> </trans-unit>
<trans-unit id="6517676116023827583" datatype="html"> <trans-unit id="6517676116023827583" datatype="html">
<source>Queued <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.queuedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.queuedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source> <source>Queued <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.queuedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.queuedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
@@ -3479,7 +3479,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">114</context> <context context-type="linenumber">114</context>
</context-group> </context-group>
<target state="needs-translation">Queued <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.queuedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.queuedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target> <target state="translated">V čakalni vrsti <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;tasksService.queuedFileTasks.length &gt; 0&quot; class=&quot;badge bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.queuedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
</trans-unit> </trans-unit>
<trans-unit id="5404910960991552159" datatype="html"> <trans-unit id="5404910960991552159" datatype="html">
<source>Dismiss selected</source> <source>Dismiss selected</source>
@@ -3487,7 +3487,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context>
<context context-type="linenumber">21</context> <context context-type="linenumber">21</context>
</context-group> </context-group>
<target state="needs-translation">Dismiss selected</target> <target state="translated">Opusti izbrano</target>
</trans-unit> </trans-unit>
<trans-unit id="8829078752502782653" datatype="html"> <trans-unit id="8829078752502782653" datatype="html">
<source>Dismiss all</source> <source>Dismiss all</source>
@@ -3499,7 +3499,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context>
<context context-type="linenumber">52</context> <context context-type="linenumber">52</context>
</context-group> </context-group>
<target state="needs-translation">Dismiss all</target> <target state="translated">Opusti vse</target>
</trans-unit> </trans-unit>
<trans-unit id="1323591410517879795" datatype="html"> <trans-unit id="1323591410517879795" datatype="html">
<source>Confirm Dismiss All</source> <source>Confirm Dismiss All</source>
@@ -3507,7 +3507,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context>
<context context-type="linenumber">50</context> <context context-type="linenumber">50</context>
</context-group> </context-group>
<target state="needs-translation">Confirm Dismiss All</target> <target state="translated">Potrdi Opusti vse</target>
</trans-unit> </trans-unit>
<trans-unit id="6566358716882976903" datatype="html"> <trans-unit id="6566358716882976903" datatype="html">
<source>tasks?</source> <source>tasks?</source>
@@ -3515,7 +3515,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.ts</context>
<context context-type="linenumber">52</context> <context context-type="linenumber">52</context>
</context-group> </context-group>
<target state="needs-translation">tasks?</target> <target state="translated">naloge?</target>
</trans-unit> </trans-unit>
<trans-unit id="181464970911903082" datatype="html"> <trans-unit id="181464970911903082" datatype="html">
<source>404 Not Found</source> <source>404 Not Found</source>
@@ -3619,7 +3619,7 @@
<context context-type="sourcefile">src/app/guards/dirty-doc.guard.ts</context> <context context-type="sourcefile">src/app/guards/dirty-doc.guard.ts</context>
<context context-type="linenumber">17</context> <context context-type="linenumber">17</context>
</context-group> </context-group>
<target state="needs-translation">Warning: You have unsaved changes to your document(s).</target> <target state="translated">Opozorilo: v dokumentih imate neshranjene spremembe.</target>
</trans-unit> </trans-unit>
<trans-unit id="159901853873315050" datatype="html"> <trans-unit id="159901853873315050" datatype="html">
<source>Unsaved Changes</source> <source>Unsaved Changes</source>
@@ -3803,7 +3803,7 @@
<context context-type="sourcefile">src/app/services/open-documents.service.ts</context> <context context-type="sourcefile">src/app/services/open-documents.service.ts</context>
<context context-type="linenumber">118</context> <context context-type="linenumber">118</context>
</context-group> </context-group>
<target state="needs-translation">You have unsaved changes to the document</target> <target state="translated">Imate neshranjene spremembe dokumenta</target>
</trans-unit> </trans-unit>
<trans-unit id="2089045849587358256" datatype="html"> <trans-unit id="2089045849587358256" datatype="html">
<source>Are you sure you want to close this document?</source> <source>Are you sure you want to close this document?</source>
@@ -3868,7 +3868,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">146</context> <context context-type="linenumber">146</context>
</context-group> </context-group>
<target state="needs-translation">Belarusian</target> <target state="translated">Beloruščina</target>
</trans-unit> </trans-unit>
<trans-unit id="2719780722934172508" datatype="html"> <trans-unit id="2719780722934172508" datatype="html">
<source>Czech</source> <source>Czech</source>
@@ -3988,7 +3988,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">236</context> <context context-type="linenumber">236</context>
</context-group> </context-group>
<target state="needs-translation">Slovenian</target> <target state="translated">Slovenščina</target>
</trans-unit> </trans-unit>
<trans-unit id="8608389829607915090" datatype="html"> <trans-unit id="8608389829607915090" datatype="html">
<source>Serbian</source> <source>Serbian</source>
@@ -3996,7 +3996,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">242</context> <context context-type="linenumber">242</context>
</context-group> </context-group>
<target state="needs-translation">Serbian</target> <target state="translated">Srbščina</target>
</trans-unit> </trans-unit>
<trans-unit id="499386805970351976" datatype="html"> <trans-unit id="499386805970351976" datatype="html">
<source>Swedish</source> <source>Swedish</source>
@@ -4012,7 +4012,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">254</context> <context context-type="linenumber">254</context>
</context-group> </context-group>
<target state="needs-translation">Turkish</target> <target state="translated">Turščina</target>
</trans-unit> </trans-unit>
<trans-unit id="4689443708886954687" datatype="html"> <trans-unit id="4689443708886954687" datatype="html">
<source>Chinese Simplified</source> <source>Chinese Simplified</source>
@@ -4020,7 +4020,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">260</context> <context context-type="linenumber">260</context>
</context-group> </context-group>
<target state="needs-translation">Chinese Simplified</target> <target state="translated">Poenostavljena kitajščina</target>
</trans-unit> </trans-unit>
<trans-unit id="4912706592792948707" datatype="html"> <trans-unit id="4912706592792948707" datatype="html">
<source>ISO 8601</source> <source>ISO 8601</source>
@@ -4036,7 +4036,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">372</context> <context context-type="linenumber">372</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="translated">Uspešno opravljena enkratna migracija nastavitev v bazo!</target>
</trans-unit> </trans-unit>
<trans-unit id="5558341108007064934" datatype="html"> <trans-unit id="5558341108007064934" datatype="html">
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
@@ -4044,7 +4044,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">373</context> <context context-type="linenumber">373</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="translated">Nastavitev ni mogoče preseliti v bazo podatkov, poskusite jih shraniti ročno.</target>
</trans-unit> </trans-unit>
<trans-unit id="1519954996184640001" datatype="html"> <trans-unit id="1519954996184640001" datatype="html">
<source>Error</source> <source>Error</source>

View File

@@ -3,12 +3,15 @@ import os
import shutil import shutil
import tempfile import tempfile
from functools import lru_cache from functools import lru_cache
from typing import List # for type hinting. Can be removed, if only Python >3.8 is used from typing import List
from typing import Optional
from typing import Tuple
import magic import magic
from django.conf import settings from django.conf import settings
from pdf2image import convert_from_path from pikepdf import Page
from pikepdf import Pdf from pikepdf import Pdf
from pikepdf import PdfImage
from PIL import Image from PIL import Image
from PIL import ImageSequence from PIL import ImageSequence
from pyzbar import pyzbar from pyzbar import pyzbar
@@ -31,7 +34,7 @@ def supported_file_type(mime_type) -> bool:
return mime_type in supported_mime return mime_type in supported_mime
def barcode_reader(image) -> List[str]: def barcode_reader(image: Image) -> List[str]:
""" """
Read any barcodes contained in image Read any barcodes contained in image
Returns a list containing all found barcodes Returns a list containing all found barcodes
@@ -98,21 +101,39 @@ def convert_from_tiff_to_pdf(filepath: str) -> str:
return newpath return newpath
def scan_file_for_separating_barcodes(filepath: str) -> List[int]: def scan_file_for_separating_barcodes(filepath: str) -> Tuple[Optional[str], List[int]]:
""" """
Scan the provided pdf file for page separating barcodes Scan the provided pdf file for page separating barcodes
Returns a list of pagenumbers, which separate the file Returns a PDF filepath and a list of pagenumbers,
which separate the file into new files
""" """
separator_page_numbers = [] separator_page_numbers = []
separator_barcode = str(settings.CONSUMER_BARCODE_STRING) pdf_filepath = None
# use a temporary directory in case the file os too big to handle in memory
with tempfile.TemporaryDirectory() as path: mime_type = get_file_mime_type(filepath)
pages_from_path = convert_from_path(filepath, output_folder=path)
for current_page_number, page in enumerate(pages_from_path): if supported_file_type(mime_type):
current_barcodes = barcode_reader(page) pdf_filepath = filepath
if separator_barcode in current_barcodes: if mime_type == "image/tiff":
separator_page_numbers.append(current_page_number) pdf_filepath = convert_from_tiff_to_pdf(filepath)
return separator_page_numbers
pdf = Pdf.open(pdf_filepath)
for page_num, page in enumerate(pdf.pages):
for image_key in page.images:
pdfimage = PdfImage(page.images[image_key])
pillow_img = pdfimage.as_pil_image()
detected_barcodes = barcode_reader(pillow_img)
if settings.CONSUMER_BARCODE_STRING in detected_barcodes:
separator_page_numbers.append(page_num)
else:
logger.warning(
f"Unsupported file format for barcode reader: {str(mime_type)}",
)
return pdf_filepath, separator_page_numbers
def separate_pages(filepath: str, pages_to_split_on: List[int]) -> List[str]: def separate_pages(filepath: str, pages_to_split_on: List[int]) -> List[str]:
@@ -122,47 +143,56 @@ def separate_pages(filepath: str, pages_to_split_on: List[int]) -> List[str]:
Returns a list of (temporary) filepaths to consume. Returns a list of (temporary) filepaths to consume.
These will need to be deleted later. These will need to be deleted later.
""" """
document_paths = []
if not pages_to_split_on:
logger.warning("No pages to split on!")
return document_paths
os.makedirs(settings.SCRATCH_DIR, exist_ok=True) os.makedirs(settings.SCRATCH_DIR, exist_ok=True)
tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR)
fname = os.path.splitext(os.path.basename(filepath))[0] fname = os.path.splitext(os.path.basename(filepath))[0]
pdf = Pdf.open(filepath) pdf = Pdf.open(filepath)
document_paths = []
logger.debug(f"Temp dir is {str(tempdir)}") # A list of documents, ie a list of lists of pages
if not pages_to_split_on: documents: List[List[Page]] = []
logger.warning("No pages to split on!") # A single document, ie a list of pages
else: document: List[Page] = []
# go from the first page to the first separator page
for idx, page in enumerate(pdf.pages):
# Keep building the new PDF as long as it is not a
# separator index
if idx not in pages_to_split_on:
document.append(page)
# Make sure to append the very last document to the documents
if idx == (len(pdf.pages) - 1):
documents.append(document)
document = []
else:
# This is a split index, save the current PDF pages, and restart
# a new destination page listing
logger.debug(f"Starting new document at idx {idx}")
documents.append(document)
document = []
documents = [x for x in documents if len(x)]
logger.debug(f"Split into {len(documents)} new documents")
# Write the new documents out
for doc_idx, document in enumerate(documents):
dst = Pdf.new() dst = Pdf.new()
for n, page in enumerate(pdf.pages): dst.pages.extend(document)
if n < pages_to_split_on[0]:
dst.pages.append(page) output_filename = f"{fname}_document_{doc_idx}.pdf"
output_filename = f"{fname}_document_0.pdf"
logger.debug(f"pdf no:{doc_idx} has {len(dst.pages)} pages")
savepath = os.path.join(tempdir, output_filename) savepath = os.path.join(tempdir, output_filename)
with open(savepath, "wb") as out: with open(savepath, "wb") as out:
dst.save(out) dst.save(out)
document_paths = [savepath] document_paths.append(savepath)
# iterate through the rest of the document
for count, page_number in enumerate(pages_to_split_on):
logger.debug(f"Count: {str(count)} page_number: {str(page_number)}")
dst = Pdf.new()
try:
next_page = pages_to_split_on[count + 1]
except IndexError:
next_page = len(pdf.pages)
# skip the first page_number. This contains the barcode page
for page in range(page_number + 1, next_page):
logger.debug(
f"page_number: {str(page_number)} next_page: {str(next_page)}",
)
dst.pages.append(pdf.pages[page])
output_filename = f"{fname}_document_{str(count + 1)}.pdf"
logger.debug(f"pdf no:{str(count)} has {str(len(dst.pages))} pages")
savepath = os.path.join(tempdir, output_filename)
with open(savepath, "wb") as out:
dst.save(out)
document_paths.append(savepath)
logger.debug(f"Temp files are {str(document_paths)}")
return document_paths return document_paths

View File

@@ -96,29 +96,13 @@ def consume_file(
# check for separators in current document # check for separators in current document
if settings.CONSUMER_ENABLE_BARCODES: if settings.CONSUMER_ENABLE_BARCODES:
mime_type = barcodes.get_file_mime_type(path) pdf_filepath, separators = barcodes.scan_file_for_separating_barcodes(path)
if not barcodes.supported_file_type(mime_type): if separators:
# if not supported, skip this routine logger.debug(
logger.warning( f"Pages with separators found in: {str(path)}",
f"Unsupported file format for barcode reader: {str(mime_type)}",
) )
else: document_list = barcodes.separate_pages(pdf_filepath, separators)
separators = []
document_list = []
if mime_type == "image/tiff":
file_to_process = barcodes.convert_from_tiff_to_pdf(path)
else:
file_to_process = path
separators = barcodes.scan_file_for_separating_barcodes(file_to_process)
if separators:
logger.debug(
f"Pages with separators found in: {str(path)}",
)
document_list = barcodes.separate_pages(file_to_process, separators)
if document_list: if document_list:
for n, document in enumerate(document_list): for n, document in enumerate(document_list):
@@ -134,15 +118,13 @@ def consume_file(
target_dir=path.parent, target_dir=path.parent,
) )
# if we got here, the document was successfully split # Delete the PDF file which was split
# and can safely be deleted os.remove(pdf_filepath)
if mime_type == "image/tiff":
# Remove the TIFF converted to PDF file # If the original was a TIFF, remove the original file as well
logger.debug(f"Deleting file {file_to_process}") if str(pdf_filepath) != str(path):
os.unlink(file_to_process) logger.debug(f"Deleting file {path}")
# Remove the original file (new file is saved above) os.unlink(path)
logger.debug(f"Deleting file {path}")
os.unlink(path)
# notify the sender, otherwise the progress bar # notify the sender, otherwise the progress bar
# in the UI stays stuck # in the UI stays stuck

View File

@@ -13,22 +13,23 @@ from PIL import Image
class TestBarcode(DirectoriesMixin, TestCase): class TestBarcode(DirectoriesMixin, TestCase):
SAMPLE_DIR = os.path.join(
os.path.dirname(__file__),
"samples",
)
BARCODE_SAMPLE_DIR = os.path.join(SAMPLE_DIR, "barcodes")
def test_barcode_reader(self): def test_barcode_reader(self):
test_file = os.path.join( test_file = os.path.join(self.BARCODE_SAMPLE_DIR, "barcode-39-PATCHT.png")
os.path.dirname(__file__),
"samples",
"barcodes",
"barcode-39-PATCHT.png",
)
img = Image.open(test_file) img = Image.open(test_file)
separator_barcode = str(settings.CONSUMER_BARCODE_STRING) separator_barcode = str(settings.CONSUMER_BARCODE_STRING)
self.assertEqual(barcodes.barcode_reader(img), [separator_barcode]) self.assertEqual(barcodes.barcode_reader(img), [separator_barcode])
def test_barcode_reader2(self): def test_barcode_reader2(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t.pbm", "patch-code-t.pbm",
) )
img = Image.open(test_file) img = Image.open(test_file)
@@ -37,9 +38,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_barcode_reader_distorsion(self): def test_barcode_reader_distorsion(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-39-PATCHT-distorsion.png", "barcode-39-PATCHT-distorsion.png",
) )
img = Image.open(test_file) img = Image.open(test_file)
@@ -48,9 +47,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_barcode_reader_distorsion2(self): def test_barcode_reader_distorsion2(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-39-PATCHT-distorsion2.png", "barcode-39-PATCHT-distorsion2.png",
) )
img = Image.open(test_file) img = Image.open(test_file)
@@ -59,9 +56,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_barcode_reader_unreadable(self): def test_barcode_reader_unreadable(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-39-PATCHT-unreadable.png", "barcode-39-PATCHT-unreadable.png",
) )
img = Image.open(test_file) img = Image.open(test_file)
@@ -69,9 +64,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_barcode_reader_qr(self): def test_barcode_reader_qr(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"qr-code-PATCHT.png", "qr-code-PATCHT.png",
) )
img = Image.open(test_file) img = Image.open(test_file)
@@ -80,9 +73,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_barcode_reader_128(self): def test_barcode_reader_128(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-128-PATCHT.png", "barcode-128-PATCHT.png",
) )
img = Image.open(test_file) img = Image.open(test_file)
@@ -90,15 +81,13 @@ class TestBarcode(DirectoriesMixin, TestCase):
self.assertEqual(barcodes.barcode_reader(img), [separator_barcode]) self.assertEqual(barcodes.barcode_reader(img), [separator_barcode])
def test_barcode_reader_no_barcode(self): def test_barcode_reader_no_barcode(self):
test_file = os.path.join(os.path.dirname(__file__), "samples", "simple.png") test_file = os.path.join(self.SAMPLE_DIR, "simple.png")
img = Image.open(test_file) img = Image.open(test_file)
self.assertEqual(barcodes.barcode_reader(img), []) self.assertEqual(barcodes.barcode_reader(img), [])
def test_barcode_reader_custom_separator(self): def test_barcode_reader_custom_separator(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-39-custom.png", "barcode-39-custom.png",
) )
img = Image.open(test_file) img = Image.open(test_file)
@@ -106,9 +95,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_barcode_reader_custom_qr_separator(self): def test_barcode_reader_custom_qr_separator(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-qr-custom.png", "barcode-qr-custom.png",
) )
img = Image.open(test_file) img = Image.open(test_file)
@@ -116,9 +103,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_barcode_reader_custom_128_separator(self): def test_barcode_reader_custom_128_separator(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-128-custom.png", "barcode-128-custom.png",
) )
img = Image.open(test_file) img = Image.open(test_file)
@@ -126,19 +111,15 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_get_mime_type(self): def test_get_mime_type(self):
tiff_file = os.path.join( tiff_file = os.path.join(
os.path.dirname(__file__), self.SAMPLE_DIR,
"samples",
"simple.tiff", "simple.tiff",
) )
pdf_file = os.path.join( pdf_file = os.path.join(
os.path.dirname(__file__), self.SAMPLE_DIR,
"samples",
"simple.pdf", "simple.pdf",
) )
png_file = os.path.join( png_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-128-custom.png", "barcode-128-custom.png",
) )
tiff_file_no_extension = os.path.join(settings.SCRATCH_DIR, "testfile1") tiff_file_no_extension = os.path.join(settings.SCRATCH_DIR, "testfile1")
@@ -173,8 +154,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_convert_error_from_pdf_to_pdf(self): def test_convert_error_from_pdf_to_pdf(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.SAMPLE_DIR,
"samples",
"simple.pdf", "simple.pdf",
) )
dst = os.path.join(settings.SCRATCH_DIR, "simple.pdf") dst = os.path.join(settings.SCRATCH_DIR, "simple.pdf")
@@ -183,117 +163,155 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_scan_file_for_separating_barcodes(self): def test_scan_file_for_separating_barcodes(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t.pdf", "patch-code-t.pdf",
) )
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, [0]) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [0])
def test_scan_file_for_separating_barcodes2(self): def test_scan_file_for_separating_barcodes2(self):
test_file = os.path.join(os.path.dirname(__file__), "samples", "simple.pdf") test_file = os.path.join(self.SAMPLE_DIR, "simple.pdf")
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, []) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [])
def test_scan_file_for_separating_barcodes3(self): def test_scan_file_for_separating_barcodes3(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t-middle.pdf", "patch-code-t-middle.pdf",
) )
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, [1]) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [1])
def test_scan_file_for_separating_barcodes4(self): def test_scan_file_for_separating_barcodes4(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"several-patcht-codes.pdf", "several-patcht-codes.pdf",
) )
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, [2, 5]) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [2, 5])
def test_scan_file_for_separating_barcodes_upsidedown(self): def test_scan_file_for_separating_barcodes_upsidedown(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t-middle_reverse.pdf", "patch-code-t-middle_reverse.pdf",
) )
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, [1]) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [1])
def test_scan_file_for_separating_qr_barcodes(self): def test_scan_file_for_separating_qr_barcodes(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t-qr.pdf", "patch-code-t-qr.pdf",
) )
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, [0]) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [0])
@override_settings(CONSUMER_BARCODE_STRING="CUSTOM BARCODE") @override_settings(CONSUMER_BARCODE_STRING="CUSTOM BARCODE")
def test_scan_file_for_separating_custom_barcodes(self): def test_scan_file_for_separating_custom_barcodes(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-39-custom.pdf", "barcode-39-custom.pdf",
) )
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, [0]) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [0])
@override_settings(CONSUMER_BARCODE_STRING="CUSTOM BARCODE") @override_settings(CONSUMER_BARCODE_STRING="CUSTOM BARCODE")
def test_scan_file_for_separating_custom_qr_barcodes(self): def test_scan_file_for_separating_custom_qr_barcodes(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-qr-custom.pdf", "barcode-qr-custom.pdf",
) )
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, [0]) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [0])
@override_settings(CONSUMER_BARCODE_STRING="CUSTOM BARCODE") @override_settings(CONSUMER_BARCODE_STRING="CUSTOM BARCODE")
def test_scan_file_for_separating_custom_128_barcodes(self): def test_scan_file_for_separating_custom_128_barcodes(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-128-custom.pdf", "barcode-128-custom.pdf",
) )
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, [0]) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [0])
def test_scan_file_for_separating_wrong_qr_barcodes(self): def test_scan_file_for_separating_wrong_qr_barcodes(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"barcode-39-custom.pdf", "barcode-39-custom.pdf",
) )
pages = barcodes.scan_file_for_separating_barcodes(test_file) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
self.assertEqual(pages, []) test_file,
)
self.assertEqual(pdf_file, test_file)
self.assertListEqual(separator_page_numbers, [])
def test_separate_pages(self): def test_separate_pages(self):
test_file = os.path.join(
self.BARCODE_SAMPLE_DIR,
"patch-code-t-middle.pdf",
)
pages = barcodes.separate_pages(test_file, [1])
self.assertEqual(len(pages), 2)
def test_separate_pages_double_code(self):
"""
GIVEN:
- Input PDF with two patch code pages in a row
WHEN:
- The input file is split
THEN:
- Only two files are output
"""
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), os.path.dirname(__file__),
"samples", "samples",
"barcodes", "barcodes",
"patch-code-t-middle.pdf", "patch-code-t-double.pdf",
) )
pages = barcodes.separate_pages(test_file, [1]) pages = barcodes.separate_pages(test_file, [1, 2])
self.assertEqual(len(pages), 2) self.assertEqual(len(pages), 2)
def test_separate_pages_no_list(self): def test_separate_pages_no_list(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t-middle.pdf", "patch-code-t-middle.pdf",
) )
with self.assertLogs("paperless.barcodes", level="WARNING") as cm: with self.assertLogs("paperless.barcodes", level="WARNING") as cm:
@@ -308,9 +326,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_save_to_dir(self): def test_save_to_dir(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t.pdf", "patch-code-t.pdf",
) )
tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR)
@@ -320,9 +336,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_save_to_dir2(self): def test_save_to_dir2(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t.pdf", "patch-code-t.pdf",
) )
nonexistingdir = "/nowhere" nonexistingdir = "/nowhere"
@@ -340,9 +354,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_save_to_dir3(self): def test_save_to_dir3(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t.pdf", "patch-code-t.pdf",
) )
tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR)
@@ -352,31 +364,36 @@ class TestBarcode(DirectoriesMixin, TestCase):
def test_barcode_splitter(self): def test_barcode_splitter(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t-middle.pdf", "patch-code-t-middle.pdf",
) )
tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR)
separators = barcodes.scan_file_for_separating_barcodes(test_file)
self.assertTrue(separators) pdf_file, separator_page_numbers = barcodes.scan_file_for_separating_barcodes(
document_list = barcodes.separate_pages(test_file, separators) test_file,
)
self.assertEqual(test_file, pdf_file)
self.assertTrue(len(separator_page_numbers) > 0)
document_list = barcodes.separate_pages(test_file, separator_page_numbers)
self.assertTrue(document_list) self.assertTrue(document_list)
for document in document_list: for document in document_list:
barcodes.save_to_dir(document, target_dir=tempdir) barcodes.save_to_dir(document, target_dir=tempdir)
target_file1 = os.path.join(tempdir, "patch-code-t-middle_document_0.pdf") target_file1 = os.path.join(tempdir, "patch-code-t-middle_document_0.pdf")
target_file2 = os.path.join(tempdir, "patch-code-t-middle_document_1.pdf") target_file2 = os.path.join(tempdir, "patch-code-t-middle_document_1.pdf")
self.assertTrue(os.path.isfile(target_file1)) self.assertTrue(os.path.isfile(target_file1))
self.assertTrue(os.path.isfile(target_file2)) self.assertTrue(os.path.isfile(target_file2))
@override_settings(CONSUMER_ENABLE_BARCODES=True) @override_settings(CONSUMER_ENABLE_BARCODES=True)
def test_consume_barcode_file(self): def test_consume_barcode_file(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t-middle.pdf", "patch-code-t-middle.pdf",
) )
dst = os.path.join(settings.SCRATCH_DIR, "patch-code-t-middle.pdf") dst = os.path.join(settings.SCRATCH_DIR, "patch-code-t-middle.pdf")
shutil.copy(test_file, dst) shutil.copy(test_file, dst)
@@ -388,9 +405,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
) )
def test_consume_barcode_tiff_file(self): def test_consume_barcode_tiff_file(self):
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t-middle.tiff", "patch-code-t-middle.tiff",
) )
dst = os.path.join(settings.SCRATCH_DIR, "patch-code-t-middle.tiff") dst = os.path.join(settings.SCRATCH_DIR, "patch-code-t-middle.tiff")
@@ -412,18 +427,17 @@ class TestBarcode(DirectoriesMixin, TestCase):
and continue archiving the file as is. and continue archiving the file as is.
""" """
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.SAMPLE_DIR,
"samples",
"simple.jpg", "simple.jpg",
) )
dst = os.path.join(settings.SCRATCH_DIR, "simple.jpg") dst = os.path.join(settings.SCRATCH_DIR, "simple.jpg")
shutil.copy(test_file, dst) shutil.copy(test_file, dst)
with self.assertLogs("paperless.tasks", level="WARNING") as cm: with self.assertLogs("paperless.barcodes", level="WARNING") as cm:
self.assertIn("Success", tasks.consume_file(dst)) self.assertIn("Success", tasks.consume_file(dst))
self.assertListEqual( self.assertListEqual(
cm.output, cm.output,
[ [
"WARNING:paperless.tasks:Unsupported file format for barcode reader: image/jpeg", "WARNING:paperless.barcodes:Unsupported file format for barcode reader: image/jpeg",
], ],
) )
m.assert_called_once() m.assert_called_once()
@@ -445,9 +459,7 @@ class TestBarcode(DirectoriesMixin, TestCase):
the user uploads a supported image file, but without extension the user uploads a supported image file, but without extension
""" """
test_file = os.path.join( test_file = os.path.join(
os.path.dirname(__file__), self.BARCODE_SAMPLE_DIR,
"samples",
"barcodes",
"patch-code-t-middle.tiff", "patch-code-t-middle.tiff",
) )
dst = os.path.join(settings.SCRATCH_DIR, "patch-code-t-middle") dst = os.path.join(settings.SCRATCH_DIR, "patch-code-t-middle")

View File

@@ -283,7 +283,9 @@ class TestConsumer(DirectoriesMixin, ConsumerMixin, TransactionTestCase):
@override_settings( @override_settings(
CONSUMER_POLLING=1, CONSUMER_POLLING=1,
CONSUMER_POLLING_DELAY=1, # please leave the delay here and down below
# see https://github.com/paperless-ngx/paperless-ngx/pull/66
CONSUMER_POLLING_DELAY=3,
CONSUMER_POLLING_RETRY_COUNT=20, CONSUMER_POLLING_RETRY_COUNT=20,
) )
class TestConsumerPolling(TestConsumer): class TestConsumerPolling(TestConsumer):
@@ -300,7 +302,7 @@ class TestConsumerRecursive(TestConsumer):
@override_settings( @override_settings(
CONSUMER_RECURSIVE=True, CONSUMER_RECURSIVE=True,
CONSUMER_POLLING=1, CONSUMER_POLLING=1,
CONSUMER_POLLING_DELAY=1, CONSUMER_POLLING_DELAY=3,
CONSUMER_POLLING_RETRY_COUNT=20, CONSUMER_POLLING_RETRY_COUNT=20,
) )
class TestConsumerRecursivePolling(TestConsumer): class TestConsumerRecursivePolling(TestConsumer):
@@ -345,7 +347,7 @@ class TestConsumerTags(DirectoriesMixin, ConsumerMixin, TransactionTestCase):
@override_settings( @override_settings(
CONSUMER_POLLING=1, CONSUMER_POLLING=1,
CONSUMER_POLLING_DELAY=1, CONSUMER_POLLING_DELAY=3,
CONSUMER_POLLING_RETRY_COUNT=20, CONSUMER_POLLING_RETRY_COUNT=20,
) )
def test_consume_file_with_path_tags_polling(self): def test_consume_file_with_path_tags_polling(self):

View File

@@ -1,4 +1,6 @@
import grp
import os import os
import pwd
import shutil import shutil
import stat import stat
@@ -32,12 +34,15 @@ def path_check(var, directory):
with open(test_file, "w"): with open(test_file, "w"):
pass pass
except PermissionError: except PermissionError:
dir_stat = os.stat(directory)
dir_mode = stat.filemode(dir_stat.st_mode)
dir_owner = pwd.getpwuid(dir_stat.st_uid).pw_name
dir_group = grp.getgrgid(dir_stat.st_gid).gr_name
messages.append( messages.append(
Error( Error(
writeable_message.format(var), writeable_message.format(var),
writeable_hint.format( writeable_hint.format(
f"\n{stat.filemode(os.stat(directory).st_mode)} " f"\n{dir_mode} {dir_owner} {dir_group} " f"{directory}\n",
f"{directory}\n",
), ),
), ),
) )

View File

@@ -1,7 +1,7 @@
from typing import Final from typing import Final
from typing import Tuple from typing import Tuple
__version__: Final[Tuple[int, int, int]] = (1, 8, 0) __version__: Final[Tuple[int, int, int]] = (1, 9, 0)
# Version string like X.Y.Z # Version string like X.Y.Z
__full_version_str__: Final[str] = ".".join(map(str, __version__)) __full_version_str__: Final[str] = ".".join(map(str, __version__))
# Version string like X.Y # Version string like X.Y

View File

@@ -1,4 +1,5 @@
import os import os
from pathlib import Path
import dateutil.parser import dateutil.parser
import requests import requests
@@ -28,6 +29,11 @@ class TikaDocumentParser(DocumentParser):
def extract_metadata(self, document_path, mime_type): def extract_metadata(self, document_path, mime_type):
tika_server = settings.TIKA_ENDPOINT tika_server = settings.TIKA_ENDPOINT
# tika does not support a PathLike, only strings
# ensure this is a string
document_path = str(document_path)
try: try:
parsed = parser.from_file(document_path, tika_server) parsed = parser.from_file(document_path, tika_server)
except Exception as e: except Exception as e:
@@ -47,10 +53,14 @@ class TikaDocumentParser(DocumentParser):
for key in parsed["metadata"] for key in parsed["metadata"]
] ]
def parse(self, document_path, mime_type, file_name=None): def parse(self, document_path: Path, mime_type, file_name=None):
self.log("info", f"Sending {document_path} to Tika server") self.log("info", f"Sending {document_path} to Tika server")
tika_server = settings.TIKA_ENDPOINT tika_server = settings.TIKA_ENDPOINT
# tika does not support a PathLike, only strings
# ensure this is a string
document_path = str(document_path)
try: try:
parsed = parser.from_file(document_path, tika_server) parsed = parser.from_file(document_path, tika_server)
except Exception as err: except Exception as err: