diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 8ab9e0b78..2e8861abb 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -102,3 +102,14 @@ body: attributes: label: Other description: Any other relevant details. + - type: checkboxes + id: required-checks + attributes: + label: Please confirm the following + options: + - label: I believe this issue is a bug that affects all users of Paperless-ngx, not something specific to my installation. + required: true + - label: I have already searched for relevant existing issues and discussions before opening this report. + required: true + - label: I have updated the title field above with a concise description. + required: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f1c78f49..3f29dbfcb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ on: env: # This is the version of pipenv all the steps will use # If changing this, change Dockerfile - DEFAULT_PIP_ENV_VERSION: "2023.10.24" + DEFAULT_PIP_ENV_VERSION: "2023.11.15" # This is the default version of Python to use in most steps which aren't specific DEFAULT_PYTHON_VERSION: "3.10" diff --git a/Dockerfile b/Dockerfile index 84f0c192f..1f9134651 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ COPY Pipfile* ./ RUN set -eux \ && echo "Installing pipenv" \ - && python3 -m pip install --no-cache-dir --upgrade pipenv==2023.10.24 \ + && python3 -m pip install --no-cache-dir --upgrade pipenv==2023.11.15 \ && echo "Generating requirement.txt" \ && pipenv requirements > requirements.txt @@ -39,6 +39,8 @@ RUN set -eux \ # - Don't leave anything extra in here FROM docker.io/python:3.11-slim-bookworm as main-app +ENV PYTHONWARNINGS="ignore:::django.http.response:517" + LABEL org.opencontainers.image.authors="paperless-ngx team " LABEL org.opencontainers.image.documentation="https://docs.paperless-ngx.com/" LABEL org.opencontainers.image.source="https://github.com/paperless-ngx/paperless-ngx" @@ -52,8 +54,8 @@ ARG TARGETARCH # Can be workflow provided, defaults set for manual building ARG JBIG2ENC_VERSION=0.29 -ARG QPDF_VERSION=11.6.3 -ARG GS_VERSION=10.02.0 +ARG QPDF_VERSION=11.6.4 +ARG GS_VERSION=10.02.1 # # Begin installation and configuration @@ -123,13 +125,13 @@ RUN set -eux \ && echo "Installing Ghostscript ${GS_VERSION}" \ && curl --fail --silent --show-error --location \ --output libgs10_${GS_VERSION}.dfsg-2_${TARGETARCH}.deb \ - https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10_${GS_VERSION}.dfsg-2_${TARGETARCH}.deb \ + https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ && curl --fail --silent --show-error --location \ --output ghostscript_${GS_VERSION}.dfsg-2_${TARGETARCH}.deb \ - https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/ghostscript_${GS_VERSION}.dfsg-2_${TARGETARCH}.deb \ + https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ && curl --fail --silent --show-error --location \ --output libgs10-common_${GS_VERSION}.dfsg-2_all.deb \ - https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10-common_${GS_VERSION}.dfsg-2_all.deb \ + https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10-common_${GS_VERSION}.dfsg-1_all.deb \ && dpkg --install ./libgs10-common_${GS_VERSION}.dfsg-2_all.deb \ && dpkg --install ./libgs10_${GS_VERSION}.dfsg-2_${TARGETARCH}.deb \ && dpkg --install ./ghostscript_${GS_VERSION}.dfsg-2_${TARGETARCH}.deb \ diff --git a/Pipfile b/Pipfile index 1e6c35bd1..10de8fb73 100644 --- a/Pipfile +++ b/Pipfile @@ -4,16 +4,16 @@ verify_ssl = true name = "pypi" [packages] -dateparser = "~=1.1" +dateparser = "~=1.2" # WARNING: django does not use semver. # Only patch versions are guaranteed to not introduce breaking changes. -django = "~=4.2.7" +django = "~=4.2.8" django-auditlog = "*" django-celery-results = "*" django-compression-middleware = "*" django-cors-headers = "*" django-extensions = "*" -django-filter = "~=23.3" +django-filter = "~=23.5" django-guardian = "*" django-multiselectfield = "*" djangorestframework = "~=3.14" @@ -33,7 +33,7 @@ inotifyrecursive = "~=0.3" langdetect = "*" mysqlclient = "*" nltk = "*" -ocrmypdf = "~=15.0" +ocrmypdf = "~=15.4" pathvalidate = "*" pdf2image = "*" psycopg2 = "*" @@ -57,7 +57,7 @@ zxing-cpp = {version = "*", platform_machine = "== 'x86_64'"} [dev-packages] # Linting -black = "*" +black = "==23.11.0" pre-commit = "*" ruff = "*" # Testing diff --git a/Pipfile.lock b/Pipfile.lock index 572c27313..cffc5dd1f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d7ef8db734997cda7c11971f2ddb66bf1918f4232b0956a9bf604c41763ce461" + "sha256": "16ab2ca4c766b98e48156c34394b7c74c400386d72e105e7ae9f68742ef9bb74" }, "pipfile-spec": 6, "requires": {}, @@ -24,11 +24,11 @@ }, "anyio": { "hashes": [ - "sha256:56a415fbc462291813a94528a779597226619c8e78af7de0507333f700011e5f", - "sha256:5a0bec7085176715be77df87fc66d6c9d70626bd752fcc85f57cdbee5b3760da" + "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee", + "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "asgiref": { "hashes": [ @@ -246,6 +246,14 @@ "markers": "python_version >= '3.7'", "version": "==4.1.0" }, + "chardet": { + "hashes": [ + "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", + "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970" + ], + "markers": "python_version >= '3.7'", + "version": "==5.2.0" + }, "charset-normalizer": { "hashes": [ "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", @@ -375,12 +383,12 @@ }, "concurrent-log-handler": { "hashes": [ - "sha256:00f5646c6e5f6fc63654536f3b44aaa2b9b74b23245e14f5258ed91ce39d12e2", - "sha256:25c88399b23c1ed52549a836ca9666cfd61f2a6aae8bfc2a1a6427f989401d65" + "sha256:157bee12914aa2a72246d1d0641ce07c1aa7a55faa3322bed02f21e60395eb82", + "sha256:1e2c6f021414e214d3dac66107894827a3e78db63018304a4f29e55ba549ac22" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==0.9.24" + "version": "==0.9.25" }, "cryptography": { "hashes": [ @@ -413,12 +421,12 @@ }, "dateparser": { "hashes": [ - "sha256:070b29b5bbf4b1ec2cd51c96ea040dc68a614de703910a91ad1abba18f9f379f", - "sha256:86b8b7517efcc558f085a142cdb7620f0921543fcabdb538c8a4c4001d8178e3" + "sha256:0b21ad96534e562920a0083e97fd45fa959882d4162acc358705144520a35830", + "sha256:7975b43a4222283e0ae15be7b4999d08c9a70e2d378ac87385b1ccf2cffbbb30" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.1.8" + "version": "==1.2.0" }, "deprecated": { "hashes": [ @@ -437,12 +445,12 @@ }, "django": { "hashes": [ - "sha256:8e0f1c2c2786b5c0e39fe1afce24c926040fad47c8ea8ad30aaf1188df29fc41", - "sha256:e1d37c51ad26186de355cbcec16613ebdabfa9689bbade9c538835205a8abbe9" + "sha256:6cb5dcea9e3d12c47834d32156b8841f533a4493c688e2718cafd51aa430ba6d", + "sha256:d69d5e36cc5d9f4eb4872be36c622878afcdce94062716cf3e25bcedcb168b62" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.2.7" + "version": "==4.2.8" }, "django-auditlog": { "hashes": [ @@ -471,12 +479,12 @@ }, "django-cors-headers": { "hashes": [ - "sha256:25aabc94d4837678c1edf442c7f68a5f5fd151f6767b0e0b01c61a2179d02711", - "sha256:bd36c7aea0d070e462f3383f0dc9ef717e5fdc2b10a99c98c285f16da84ffba2" + "sha256:0b1fd19297e37417fc9f835d39e45c8c642938ddba1acce0c1753d3edef04f36", + "sha256:0bf65ef45e606aff1994d35503e6b677c0b26cafff6506f8fd7187f3be840207" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.3.0" + "version": "==4.3.1" }, "django-extensions": { "hashes": [ @@ -489,12 +497,12 @@ }, "django-filter": { "hashes": [ - "sha256:015fe155582e1805b40629344e4a6cf3cc40450827d294d040b4b8c1749a9fa6", - "sha256:65bc5d1d8f4fff3aaf74cb5da537b6620e9214fb4b3180f6c560776b1b6dccd0" + "sha256:67583aa43b91fe8c49f74a832d95f4d8442be628fd4c6d65e9f811f5153a4e5c", + "sha256:99122a201d83860aef4fe77758b69dda913e874cc5e0eaa50a86b0b18d708400" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==23.3" + "version": "==23.5" }, "django-guardian": { "hashes": [ @@ -599,97 +607,117 @@ }, "hiredis": { "hashes": [ - "sha256:071c5814b850574036506a8118034f97c3cbf2fe9947ff45a27b07a48da56240", - "sha256:08415ea74c1c29b9d6a4ca3dd0e810dc1af343c1d1d442e15ba133b11ab5be6a", - "sha256:126623b03c31cb6ac3e0d138feb6fcc36dd43dd34fc7da7b7a0c38b5d75bc896", - "sha256:14824e457e4f5cda685c3345d125da13949bcf3bb1c88eb5d248c8d2c3dee08f", - "sha256:15c2a551f3b8a26f7940d6ee10b837810201754b8d7e6f6b1391655370882c5a", - "sha256:17e938d9d3ee92e1adbff361706f1c36cc60eeb3e3eeca7a3a353eae344f4c91", - "sha256:1cadb0ac7ba3babfd804e425946bec9717b320564a1390f163a54af9365a720a", - "sha256:1d274d5c511dfc03f83f997d3238eaa9b6ee3f982640979f509373cced891e98", - "sha256:20f509e3a1a20d6e5f5794fc37ceb21f70f409101fcfe7a8bde783894d51b369", - "sha256:227c5b4bcb60f89008c275d596e4a7b6625a6b3c827b8a66ae582eace7051f71", - "sha256:232d0a70519865741ba56e1dfefd160a580ae78c30a1517bad47b3cf95a3bc7d", - "sha256:2443659c76b226267e2a04dbbb21bc2a3f91aa53bdc0c22964632753ae43a247", - "sha256:2d7e459fe7313925f395148d36d9b7f4f8dac65be06e45d7af356b187cef65fc", - "sha256:2fb9300959a0048138791f3d68359d61a788574ec9556bddf1fec07f2dbc5320", - "sha256:334f2738700b20faa04a0d813366fb16ed17287430a6b50584161d5ad31ca6d7", - "sha256:33a94d264e6e12a79d9bb8af333b01dc286b9f39c99072ab5fef94ce1f018e17", - "sha256:33bc4721632ef9708fa44e5df0066053fccc8e65410a2c48573192517a533b48", - "sha256:33ee3ea5cad3a8cb339352cd230b411eb437a2e75d7736c4899acab32056ccdb", - "sha256:3753df5f873d473f055e1f8837bfad0bd3b277c86f3c9bf058c58f14204cd901", - "sha256:3759f4789ae1913b7df278dfc9e8749205b7a106f888cd2903d19461e24a7697", - "sha256:3b7fe075e91b9d9cff40eba4fb6a8eff74964d3979a39be9a9ef58b1b4cb3604", - "sha256:3bf4b5bae472630c229518e4a814b1b68f10a3d9b00aeaec45f1a330f03a0251", - "sha256:3f006c28c885deb99b670a5a66f367a175ab8955b0374029bad7111f5357dcd4", - "sha256:3f5446068197b35a11ccc697720c41879c8657e2e761aaa8311783aac84cef20", - "sha256:3fa6811a618653164f918b891a0fa07052bd71a799defa5c44d167cac5557b26", - "sha256:46525fbd84523cac75af5bf524bc74aaac848beaf31b142d2df8a787d9b4bbc4", - "sha256:477c34c4489666dc73cb5e89dafe2617c3e13da1298917f73d55aac4696bd793", - "sha256:4b3e974ad15eb32b1f537730dea70b93a4c3db7b026de3ad2b59da49c6f7454d", - "sha256:4c3b8be557e08b234774925622e196f0ee36fe4eab66cd19df934d3efd8f3743", - "sha256:4e3e3e31423f888d396b1fc1f936936e52af868ac1ec17dd15e3eeba9dd4de24", - "sha256:4e43e2b5acaad09cf48c032f7e4926392bb3a3f01854416cf6d82ebff94d5467", - "sha256:4ed68a3b1ccb4313d2a42546fd7e7439ad4745918a48b6c9bcaa61e1e3e42634", - "sha256:4f674e309cd055ee7a48304ceb8cf43265d859faf4d7d01d270ce45e976ae9d3", - "sha256:50171f985e17970f87d5a29e16603d1e5b03bdbf5c2691a37e6c912942a6b657", - "sha256:51341e70b467004dcbec3a6ce8c478d2d6241e0f6b01e4c56764afd5022e1e9d", - "sha256:5a4bcef114fc071d5f52c386c47f35aae0a5b43673197b9288a15b584da8fa3a", - "sha256:5a5c8019ff94988d56eb49b15de76fe83f6b42536d76edeb6565dbf7fe14b973", - "sha256:5cda592405bbd29d53942e0389dc3fa77b49c362640210d7e94a10c14a677d4d", - "sha256:5e6674a017629284ef373b50496d9fb1a89b85a20a7fa100ecd109484ec748e5", - "sha256:5e7bb4dd524f50b71c20ef5a12bd61da9b463f8894b18a06130942fe31509881", - "sha256:60c4e3c258eafaab21b174b17270a0cc093718d61cdbde8c03f85ec4bf835343", - "sha256:61995eb826009d99ed8590747bc0da683a5f4fbb4faa8788166bf3810845cd5c", - "sha256:61a72e4a523cdfc521762137559c08dfa360a3caef63620be58c699d1717dac1", - "sha256:69536b821dd1bc78058a6e7541743f8d82bf2d981b91280b14c4daa6cdc7faba", - "sha256:6ccdcb635dae85b006592f78e32d97f4bc7541cb27829d505f9c7fefcef48298", - "sha256:6f88cafe46612b6fa68e6dea49e25bebf160598bba00101caa51cc8c1f18d597", - "sha256:6f969edc851efe23010e0f53a64269f2629a9364135e9ec81c842e8b2277d0c1", - "sha256:77924b0d32fd1f493d3df15d9609ddf9d94c31a364022a6bf6b525ce9da75bea", - "sha256:7df645b6b7800e8b748c217fbd6a4ca8361bcb9a1ae6206cc02377833ec8a1aa", - "sha256:7e17d04ea58ab8cf3f2dc52e875db16077c6357846006780086fff3189fb199d", - "sha256:7f2b34a6444b8f9c1e9f84bd2c639388e5d14f128afd14a869dfb3d9af893aa2", - "sha256:818dfd310aa1020a13cd08ee48e116dd8c3bb2e23b8161f8ac4df587dd5093d7", - "sha256:89a258424158eb8b3ed9f65548d68998da334ef155d09488c5637723eb1cd697", - "sha256:8eceffca3941775b646cd585cd19b275d382de43cc3327d22f7c75d7b003d481", - "sha256:8f280ab4e043b089777b43b4227bdc2035f88da5072ab36588e0ccf77d45d058", - "sha256:8f9dbe12f011a9b784f58faecc171d22465bb532c310bd588d769ba79a59ef5a", - "sha256:9076ce8429785c85f824650735791738de7143f61f43ae9ed83e163c0ca0fa44", - "sha256:95d2305fd2a7b179cacb48b10f618872fc565c175f9f62b854e8d1acac3e8a9e", - "sha256:96d9ea6c8d4cbdeee2e0d43379ce2881e4af0454b00570677c59f33f2531cd38", - "sha256:9944a2cac25ffe049a7e89f306e11b900640837d1ef38d9be0eaa4a4e2b73a52", - "sha256:9a1a80a8fa767f2fdc3870316a54b84fe9fc09fa6ab6a2686783de6a228a4604", - "sha256:9cd32326dfa6ce87edf754153b0105aca64486bebe93b9600ccff74fa0b224df", - "sha256:9f4a65276f6ecdebe75f2a53f578fbc40e8d2860658420d5e0611c56bbf5054c", - "sha256:a286ded34eb16501002e3713b3130c987366eee2ba0d58c33c72f27778e31676", - "sha256:a2df98f5e071320c7d84e8bd07c0542acdd0a7519307fc31774d60e4b842ec4f", - "sha256:a7205497d7276a81fe92951a29616ef96562ed2f91a02066f72b6f93cb34b40e", - "sha256:aa17a3b22b3726d54d7af20394f65d4a1735a842a4e0f557dc67a90f6965c4bc", - "sha256:af33f370be90b48bbaf0dab32decbdcc522b1fa95d109020a963282086518a8e", - "sha256:b17baf702c6e5b4bb66e1281a3efbb1d749c9d06cdb92b665ad81e03118f78fc", - "sha256:b4f3d06dc16671b88a13ae85d8ca92534c0b637d59e49f0558d040a691246422", - "sha256:b9953d87418ac228f508d93898ab572775e4d3b0eeb886a1a7734553bcdaf291", - "sha256:b9a7c987e161e3c58f992c63b7e26fea7fe0777f3b975799d23d65bbb8cb5899", - "sha256:c6cb613148422c523945cdb8b6bed617856f2602fd8750e33773ede2616e55d5", - "sha256:c9b9e5bde7030cae83aa900b5bd660decc65afd2db8c400f3c568c815a47ca2a", - "sha256:cc36a9dded458d4e37492fe3e619c6c83caae794d26ad925adbce61d592f8428", - "sha256:cd2614f17e261f72efc2f19f5e5ff2ee19e2296570c0dcf33409e22be30710de", - "sha256:d115790f18daa99b5c11a506e48923b630ef712e9e4b40482af942c3d40638b8", - "sha256:d194decd9608f11c777946f596f31d5aacad13972a0a87829ae1e6f2d26c1885", - "sha256:d1a4ce40ba11da9382c14da31f4f9e88c18f7d294f523decd0fadfb81f51ad18", - "sha256:d1be9e30e675f5bc1cb534633324578f6f0944a1bcffe53242cf632f554f83b6", - "sha256:d20891e3f33803b26d54c77fd5745878497091e33f4bbbdd454cf6e71aee8890", - "sha256:d27e560eefb57914d742a837f1da98d3b29cb22eff013c8023b7cf52ae6e051d", - "sha256:dcb0569dd5bfe6004658cd0f229efa699a3169dcb4f77bd72e188adda302063d", - "sha256:e62ec131816c6120eff40dffe43424e140264a15fa4ab88c301bd6a595913af3", - "sha256:e75163773a309e56a9b58165cf5a50e0f84b755f6ff863b2c01a38918fe92daa", - "sha256:ec58fb7c2062f835595c12f0f02dcda76d0eb0831423cc191d1e18c9276648de", - "sha256:f1eadbcd3de55ac42310ff82550d3302cb4efcd4e17d76646a17b6e7004bb42b", - "sha256:f2dcb8389fa3d453927b1299f46bdb38473c293c8269d5c777d33ea0e526b610", - "sha256:ffaf841546905d90ff189de7397aa56413b1ce5e54547f17a98f0ebf3a3b0a3b" + "sha256:01b6c24c0840ac7afafbc4db236fd55f56a9a0919a215c25a238f051781f4772", + "sha256:02fc71c8333586871602db4774d3a3e403b4ccf6446dc4603ec12df563127cee", + "sha256:0c0773266e1c38a06e7593bd08870ac1503f5f0ce0f5c63f2b4134b090b5d6a4", + "sha256:0c5f6972d2bdee3cd301d5c5438e31195cf1cabf6fd9274491674d4ceb46914d", + "sha256:0da56915bda1e0a49157191b54d3e27689b70960f0685fdd5c415dacdee2fbed", + "sha256:14c7b43205e515f538a9defb4e411e0f0576caaeeda76bb9993ed505486f7562", + "sha256:16b01d9ceae265d4ab9547be0cd628ecaff14b3360357a9d30c029e5ae8b7e7f", + "sha256:1979334ccab21a49c544cd1b8d784ffb2747f99a51cb0bd0976eebb517628382", + "sha256:1c4c0bcf786f0eac9593367b6279e9b89534e008edbf116dcd0de956524702c8", + "sha256:1d63318ca189fddc7e75f6a4af8eae9c0545863619fb38cfba5f43e81280b286", + "sha256:27e9619847e9dc70b14b1ad2d0fb4889e7ca18996585c3463cff6c951fd6b10b", + "sha256:28adecb308293e705e44087a1c2d557a816f032430d8a2a9bb7873902a1c6d48", + "sha256:28bd184b33e0dd6d65816c16521a4ba1ffbe9ff07d66873c42ea4049a62fed83", + "sha256:322c668ee1c12d6c5750a4b1057e6b4feee2a75b3d25d630922a463cfe5e7478", + "sha256:333b5e04866758b11bda5f5315b4e671d15755fc6ed3b7969721bc6311d0ee36", + "sha256:33d5ebc93c39aed4b5bc769f8ce0819bc50e74bb95d57a35f838f1c4378978e0", + "sha256:380e029bb4b1d34cf560fcc8950bf6b57c2ef0c9c8b7c7ac20b7c524a730fadd", + "sha256:387f655444d912a963ab68abf64bf6e178a13c8e4aa945cb27388fd01a02e6f1", + "sha256:3dd63d0bbbe75797b743f35d37a4cca7ca7ba35423a0de742ae2985752f20c6d", + "sha256:419780f8583ddb544ffa86f9d44a7fcc183cd826101af4e5ffe535b6765f5f6b", + "sha256:4852f4bf88f0e2d9bdf91279892f5740ed22ae368335a37a52b92a5c88691140", + "sha256:49532d7939cc51f8e99efc326090c54acf5437ed88b9c904cc8015b3c4eda9c9", + "sha256:4baf4b579b108062e91bd2a991dc98b9dc3dc06e6288db2d98895eea8acbac22", + "sha256:4d59f88c4daa36b8c38e59ac7bffed6f5d7f68eaccad471484bf587b28ccc478", + "sha256:4fc242e9da4af48714199216eb535b61e8f8d66552c8819e33fc7806bd465a09", + "sha256:532a84a82156a82529ec401d1c25d677c6543c791e54a263aa139541c363995f", + "sha256:5341ce3d01ef3c7418a72e370bf028c7aeb16895e79e115fe4c954fff990489e", + "sha256:53d0f2c59bce399b8010a21bc779b4f8c32d0f582b2284ac8c98dc7578b27bc4", + "sha256:55ce31bf4711da879b96d511208efb65a6165da4ba91cb3a96d86d5a8d9d23e6", + "sha256:56e9b7d6051688ca94e68c0c8a54a243f8db841911b683cedf89a29d4de91509", + "sha256:57c0d0c7e308ed5280a4900d4468bbfec51f0e1b4cde1deae7d4e639bc6b7766", + "sha256:5986fb5f380169270a0293bebebd95466a1c85010b4f1afc2727e4d17c452512", + "sha256:5bd42d0d45ea47a2f96babd82a659fbc60612ab9423a68e4a8191e538b85542a", + "sha256:5c614552c6bd1d0d907f448f75550f6b24fb56cbfce80c094908b7990cad9702", + "sha256:63a090761ddc3c1f7db5e67aa4e247b4b3bb9890080bdcdadd1b5200b8b89ac4", + "sha256:63b99b5ea9fe4f21469fb06a16ca5244307678636f11917359e3223aaeca0b67", + "sha256:66ab949424ac6504d823cba45c4c4854af5c59306a1531edb43b4dd22e17c102", + "sha256:684840b014ce83541a087fcf2d48227196576f56ae3e944d4dfe14c0a3e0ccb7", + "sha256:6871306d8b98a15e53a5f289ec1106a3a1d43e7ab6f4d785f95fcef9a7bd9504", + "sha256:6b4edee59dc089bc3948f4f6fba309f51aa2ccce63902364900aa0a553a85e97", + "sha256:6d7302b4b17fcc1cc727ce84ded7f6be4655701e8d58744f73b09cb9ed2b13df", + "sha256:6dbfe1887ffa5cf3030451a56a8f965a9da2fa82b7149357752b67a335a05fc6", + "sha256:70d226ab0306a5b8d408235cabe51d4bf3554c9e8a72d53ce0b3c5c84cf78881", + "sha256:7298562a49d95570ab1c7fc4051e72824c6a80e907993a21a41ba204223e7334", + "sha256:733e2456b68f3f126ddaf2cd500a33b25146c3676b97ea843665717bda0c5d43", + "sha256:742093f33d374098aa21c1696ac6e4874b52658c870513a297a89265a4d08fe5", + "sha256:7bac7e02915b970c3723a7a7c5df4ba7a11a3426d2a3f181e041aa506a1ff028", + "sha256:7e8bf4444b09419b77ce671088db9f875b26720b5872d97778e2545cd87dba4a", + "sha256:7f39f28ffc65de577c3bc0c7615f149e35bc927802a0f56e612db9b530f316f9", + "sha256:80441b55edbef868e2563842f5030982b04349408396e5ac2b32025fb06b5212", + "sha256:80b02d27864ebaf9b153d4b99015342382eeaed651f5591ce6f07e840307c56d", + "sha256:88cb0b35b63717ef1e41d62f4f8717166f7c6245064957907cfe177cc144357c", + "sha256:8c490191fa1218851f8a80c5a21a05a6f680ac5aebc2e688b71cbfe592f8fec6", + "sha256:8e3f8b1733078ac663dad57e20060e16389a60ab542f18a97931f3a2a2dd64a4", + "sha256:8f34801b251ca43ad70691fb08b606a2e55f06b9c9fb1fc18fd9402b19d70f7b", + "sha256:8fc7197ff33047ce43a67851ccf190acb5b05c52fd4a001bb55766358f04da68", + "sha256:92830c16885f29163e1c2da1f3c1edb226df1210ec7e8711aaabba3dd0d5470a", + "sha256:9412a06b8a8e09abd6313d96864b6d7713c6003a365995a5c70cfb9209df1570", + "sha256:948d9f2ca7841794dd9b204644963a4bcd69ced4e959b0d4ecf1b8ce994a6daa", + "sha256:9a0026cfbf29f07649b0e34509091a2a6016ff8844b127de150efce1c3aff60b", + "sha256:9c431431abf55b64347ddc8df68b3ef840269cb0aa5bc2d26ad9506eb4b1b866", + "sha256:9e14fb70ca4f7efa924f508975199353bf653f452e4ef0a1e47549e208f943d7", + "sha256:a45857e87e9d2b005e81ddac9d815a33efd26ec67032c366629f023fe64fb415", + "sha256:a50c8af811b35b8a43b1590cf890b61ff2233225257a3cad32f43b3ec7ff1b9f", + "sha256:a6481c3b7673a86276220140456c2a6fbfe8d1fb5c613b4728293c8634134824", + "sha256:a6b54dabfaa5dbaa92f796f0c32819b4636e66aa8e9106c3d421624bd2a2d676", + "sha256:a797d8c7df9944314d309b0d9e1b354e2fa4430a05bb7604da13b6ad291bf959", + "sha256:a91a14dd95e24dc078204b18b0199226ee44644974c645dc54ee7b00c3157330", + "sha256:adfbf2e9c38b77d0db2fb32c3bdaea638fa76b4e75847283cd707521ad2475ef", + "sha256:ba3dc0af0def8c21ce7d903c59ea1e8ec4cb073f25ece9edaec7f92a286cd219", + "sha256:bb777a38797c8c7df0444533119570be18d1a4ce5478dffc00c875684df7bfcb", + "sha256:bcbe47da0aebc00a7cfe3ebdcff0373b86ce2b1856251c003e3d69c9db44b5a7", + "sha256:bd1cee053416183adcc8e6134704c46c60c3f66b8faaf9e65bf76191ca59a2f7", + "sha256:bd40d2e2f82a483de0d0a6dfd8c3895a02e55e5c9949610ecbded18188fd0a56", + "sha256:bfa73e3f163c6e8b2ec26f22285d717a5f77ab2120c97a2605d8f48b26950dac", + "sha256:c1f567489f422d40c21e53212a73bef4638d9f21043848150f8544ef1f3a6ad1", + "sha256:c3dde4ca00fe9eee3b76209711f1941bb86db42b8a75d7f2249ff9dfc026ab0e", + "sha256:c8937f1100435698c18e4da086968c4b5d70e86ea718376f833475ab3277c9aa", + "sha256:ca33c175c1cf60222d9c6d01c38fc17ec3a484f32294af781de30226b003e00f", + "sha256:ce42649e2676ad783186264d5ffc788a7612ecd7f9effb62d51c30d413a3eefe", + "sha256:cfa67afe2269b2d203cd1389c00c5bc35a287cd57860441fb0e53b371ea6a029", + "sha256:d47c915897a99d0d34a39fad4be97b4b709ab3d0d3b779ebccf2b6024a8c681e", + "sha256:d4dd676107a1d3c724a56a9d9db38166ad4cf44f924ee701414751bd18a784a0", + "sha256:d711c107e83117129b7f8bd08e9820c43ceec6204fff072a001fd82f6d13db9f", + "sha256:dc1c3fd49930494a67dcec37d0558d99d84eca8eb3f03b17198424538f2608d7", + "sha256:de3a32b4b76d46f1eb42b24a918d51d8ca52411a381748196241d59a895f7c5c", + "sha256:dfa904045d7cebfb0f01dad51352551cce1d873d7c3f80c7ded7d42f8cac8f89", + "sha256:e138d141ec5a6ec800b6d01ddc3e5561ce1c940215e0eb9960876bfde7186aae", + "sha256:e15a408f71a6c8c87b364f1f15a6cd9c1baca12bbc47a326ac8ab99ec7ad3c64", + "sha256:e1d86b75de787481b04d112067a4033e1ecfda2a060e50318a74e4e1c9b2948c", + "sha256:e2674a5a3168349435b08fa0b82998ed2536eb9acccf7087efe26e4cd088a525", + "sha256:e58494f282215fc461b06709e9a195a24c12ba09570f25bdf9efb036acc05101", + "sha256:e627d8ef5e100556e09fb44c9571a432b10e11596d3c4043500080ca9944a91a", + "sha256:e741ffe4e2db78a1b9dd6e5d29678ce37fbaaf65dfe132e5b82a794413302ef1", + "sha256:e81aa4e9a1fcf604c8c4b51aa5d258e195a6ba81efe1da82dea3204443eba01c", + "sha256:e96cd35df012a17c87ae276196ea8f215e77d6eeca90709eb03999e2d5e3fd8a", + "sha256:ea002656a8d974daaf6089863ab0a306962c8b715db6b10879f98b781a2a5bf5", + "sha256:eae62ed60d53b3561148bcd8c2383e430af38c0deab9f2dd15f8874888ffd26f", + "sha256:eb8797b528c1ff81eef06713623562b36db3dafa106b59f83a6468df788ff0d1", + "sha256:eb98038ccd368e0d88bd92ee575c58cfaf33e77f788c36b2a89a84ee1936dc6b", + "sha256:ec444ab8f27562a363672d6a7372bc0700a1bdc9764563c57c5f9efa0e592b5f", + "sha256:ed63e8b75c193c5e5a8288d9d7b011da076cc314fafc3bfd59ec1d8a750d48c8", + "sha256:f2c9c0d910dd3f7df92f0638e7f65d8edd7f442203caf89c62fc79f11b0b73f8", + "sha256:f3020b60e3fc96d08c2a9b011f1c2e2a6bdcc09cb55df93c509b88be5cb791df", + "sha256:f47775e27388b58ce52f4f972f80e45b13c65113e9e6b6bf60148f893871dc9b", + "sha256:f70481213373d44614148f0f2e38e7905be3f021902ae5167289413196de4ba4", + "sha256:f9de7586522e5da6bee83c9cf0dcccac0857a43249cb4d721a2e312d98a684d1", + "sha256:f9f606e810858207d4b4287b4ef0dc622c2aa469548bf02b59dcc616f134f811", + "sha256:fa45f7d771094b8145af10db74704ab0f698adb682fbf3721d8090f90e42cc49" ], - "version": "==2.2.3" + "version": "==2.3.2" }, "hpack": { "hashes": [ @@ -761,11 +789,11 @@ }, "humanize": { "hashes": [ - "sha256:8bc9e2bb9315e61ec06bf690151ae35aeb65651ab091266941edf97c90836404", - "sha256:9783373bf1eec713a770ecaa7c2d7a7902c98398009dfa3d8a2df91eec9311e8" + "sha256:582a265c931c683a7e9b8ed9559089dea7edcf6cc95be39a3cbc2c5d5ac2bcfa", + "sha256:ce284a76d5b1377fd8836733b983bfb0b76f1aa1c090de2566fcf008d7f6ab16" ], "markers": "python_version >= '3.8'", - "version": "==4.8.0" + "version": "==4.9.0" }, "hyperframe": { "hashes": [ @@ -1015,17 +1043,19 @@ }, "mysqlclient": { "hashes": [ - "sha256:004fe1d30d2c2ff8072f8ea513bcec235fd9b896f70dad369461d0ad7e570e98", - "sha256:04368445f9c487d8abb7a878e3d23e923e6072c04a6c320f9e0dc8a82efba14e", - "sha256:530ece9995a36cadb6211b9787f0c9e05cdab6702549bdb4236af5e9b535ed6a", - "sha256:5670679ff1be1cc3fef0fa81bf39f0cd70605ba121141050f02743eb878ac114", - "sha256:68837b6bb23170acffb43ae411e47533a560b6360c06dac39aa55700972c93b2", - "sha256:955dba905a7443ce4788c63fdb9f8d688316260cf60b20ff51ac3b1c77616ede", - "sha256:9c6b142836c7dba4f723bf9c93cc46b6e5081d65b2af807f400dda9eb85a16d0" + "sha256:1f8889cc5f0141bb307b915e981a66793df663ace92259344661084a7dd8d12a", + "sha256:2c7ad15b87293b12fd44b47c46879ec95ec647f4567e866ccd70b8337584e9b2", + "sha256:45600f4f321096bd1ead3355bc62cfcf8d97dc78df94e4ab5db72ecb5db1bd04", + "sha256:4fabe1f4b545ed6244ad0ff426e6b27054b7e5c5b1392be0de2e5f2f59be0392", + "sha256:641a7c9de443ddef186a0e89f24b4251ad44f4ddc5e7094332bf2d286d7c9e33", + "sha256:8f40c872f19639366e3df27bef2ff087be0e3ee0bd3453470bd29f46b54a90f6", + "sha256:97eee76818774bb695e018ff4c3dafaab74b9a0b0cf32c90b02caeec3b19cd8e", + "sha256:9db6305cdf2a1da350f827d2a19be7f2666eafd9eb8d4f7cbbac5df847d61b99", + "sha256:c5a293baebbfcfa2905545198a54e90f1cf00f211eae6637d24930abb6432cba" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.2.0" + "version": "==2.2.1" }, "nltk": { "hashes": [ @@ -1080,12 +1110,12 @@ }, "ocrmypdf": { "hashes": [ - "sha256:63803b21f80925170cc96dec11833a6cb740be377e50adfaa210b2c26e64b67a", - "sha256:9385f582fa8b9eb4d89a27dfd80a29cffdf53694c570f9f0e87db4af8cfe3b15" + "sha256:13fd388035b5f4bb673bff570cfc2cf72e51168646d5401de9e48ca355917c6d", + "sha256:4696c81cc5b5d64f31ccfe685d10baeb69b42bb0974acddf292d8cf9d97605c3" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==15.4.3" + "version": "==15.4.4" }, "packaging": { "hashes": [ @@ -1122,41 +1152,41 @@ }, "pikepdf": { "hashes": [ - "sha256:08070185661db9dfbaec014094fec9e323d8ab882dc458a07383f55e08bfdd22", - "sha256:0f118446960213c78b21fe106890028dcaff739369bceda9008719b43670e290", - "sha256:1e982dbf2d25df72975e2d336ca6a5a8565add156bfdba328beb67b324a1689e", - "sha256:2771cba79c62b3f9d93cffa684a92d60e6050f727d4f52220d8180eaf967c4bf", - "sha256:2a320bfa4caa73d00d90b04433305b3ff7a6c63bdf36f55af16725066fe46b49", - "sha256:3748c4d67b40c26fa777d1f3eefcab4bcca101395ad54502020653024d23c37d", - "sha256:3956b2abda0ef86b37b5d49066c3adfd29d056ed96b1ef93bacbd269c78c5e13", - "sha256:3b719a40f1b08da1ff6fd87b3847d4ce033f8ffd81a13dca8c3c947a080c071d", - "sha256:3ff178684ed43de28ca3e7dcf9da5082ebf49bcd042e9308ffaa0162275da1a4", - "sha256:42360df95f08164162af465c493d1e612d3c0ff6d23dc17be073380b05db715c", - "sha256:5075a2a741ba23212e963d9ea3fc7a4f9394535fab11fdc7ea4641d61cab0287", - "sha256:67276e1731dc8b2f58663ff62b4728f9e0046c8217768fe0649428315cfe8253", - "sha256:69d69a93d07027e351996ef8232f26bba762d415206414e0ae3814be0aee0f7a", - "sha256:7075c79fa5d85b0acf1536a1849bcbb4e661b33f476c7c6d81255df247b2ae1f", - "sha256:7bd88db0b68da1d04dd5a1ed0897e37ef1968317a887781b1e26c1649bbd11e3", - "sha256:80275466282495c672264801b50c7188f86590779f3ada8148336e3e84fd06c0", - "sha256:897cac14f9e3db97d4effea50190e6c59e87d4147da98ff6108d254dcc1949d9", - "sha256:8a1ac9e17d890b39f717b040eaebc79325ff23278756805220138f054599f9f0", - "sha256:8e687681f26533fee69904403fdf4fc2a1f0e47480b5bfbba64139c07d72c9d2", - "sha256:9430eb3439c0e9cb1b477115d5a34905f5c6be55422d66fcba55cedbf711ae89", - "sha256:94737db4beb7391ca78627e461050c5dd3a7cb7526fd6bdd0a0db94780e8b103", - "sha256:94998ff1d15b0eaec76494266e2e61d80573c5ee4ac0860a9af4a02e5107fe17", - "sha256:a9da8d1db2d7e17411afef351ea9ccddbff36ce748b16003d4f065250c941436", - "sha256:c11acef5c211af2559e1753ed96b3b4f30e7a9e26acad4b2cbd55ea3b25e3154", - "sha256:c631c6fd16b44a2636988d8be7202f1ffd3932f505e8b9044a6b88ef62411871", - "sha256:d0678ed952a85f4b3b23d5ee94445e55a05aec0b47de37843625eba1f9b0fbb3", - "sha256:d7899f43a198d184c3d4787390a67c654a8c600c6c844f29b557b4f236d11619", - "sha256:dc8f0116237d2f07fd8a8763f2c59f2fa50f445471f0c619914075ec411920e2", - "sha256:dd5ad4cb6244ac885512f5385f6fc055e2bfc174636189fc1408f138458380c8", - "sha256:e93d706b40cebc3b2fdaa9e814b4008ed4c659c6df03ee6a4ed46683aa21ab24", - "sha256:ece366b8e68be47a7252c27f73dd9666df6871fb6e302a7bfd00a5cb293743f2", - "sha256:f3781b8dc868e3d452ce36348b26735d7a2fc0fe6a4503f72411e5bc9341a7fa" + "sha256:0054d2d762c74461d9d63f19a9a7e04d31ca321a442b068d72411320190d8535", + "sha256:0ed9c0f2908e05e8fdeab14ad73d25924da90f57d3485f3a01acfac6078396af", + "sha256:11362e7ee8b713e0e4eeece1e5548f201eaeb4a545694bd79f677c9f65e42edf", + "sha256:1855eda39e1fa51109acfff2d6b0536cad126b7326ec42f768edf56fcc8cb09a", + "sha256:1c5206fd985047a21e4201d4647b5b0960657397e6e611de01da85523b90259a", + "sha256:2991e509d8d960e7f66bbfec7fee2025024a09282485e8f925f154e03957b6e0", + "sha256:2c40c140f8ab96320de2ed2317b6d88891581161c1d3caa24642ae7e4da0d472", + "sha256:31ac851bcec64162f1e2b2f8ab5418ee7e0c9c6bd993cf70999e13a75479f265", + "sha256:3be9e0e78aa7d32960e4b317e1f63a0e58f87cbd9b14faeb45632d40b735ae53", + "sha256:55c017d49c6fe48b99d1e8d6cbcaa9fbdb33e3f6fe515d5d0a7a02fbec336821", + "sha256:5a74e32dfef4bacc2cb0f82f68be3881f94f34cc8cd0f1b00845fcfebc071512", + "sha256:5d3c0ab403f7130e4dffce08f468cd385989795026e4caccb98aa4304e048c0d", + "sha256:650fba70cbafb1c14b94e76de31bb42b9f14263517f32b19e8305ffac35383e6", + "sha256:6763982e6092db85a36d30ae1b66f4c664abbd37f2eca58b1d06f5cf4607a86a", + "sha256:6c061cbbd0d70322c8cd40132d1a595b962659f1cdf74c31ae209f8afa6cc85b", + "sha256:704c22ba8c976dafebd58c24701aa9729777b52c1b021198e7201b25c0f1372f", + "sha256:7145a023d3dec50043a3649086a07824b09c92351aa1e9ff669513811fc942f2", + "sha256:8519d3871643b7d287e976b3567c36cf5b01f010e7dc19fa37496f8e1f6f01ec", + "sha256:8cc8129189e79f994bf1ca4d3da16575f267f7cac6ffd8df0e04d5309be2c154", + "sha256:9346c3baa64ae72e017175b74615952f9fc5f8a22fe51764852cdf2d2419c89e", + "sha256:9b1fc398f95fcce7e0aa6b0786bd092cab805afd01dc6a79c9c59e080c5c8801", + "sha256:9ff213799f7326a01faa7d0b940aa7d19693ff0eb3785bb7dfe81243ebcf9235", + "sha256:a1e344de5abdb1d873203083e318dd492d66431feb8994ac0d185e3563694331", + "sha256:c002273070553a6547012c9ab55bace154edcd92fbdacbb4499c8725e3d7d92a", + "sha256:c336bc08b8ce97c33733d6e048e207b4b8cca27cce2f9c28b084937c5a335cba", + "sha256:d92c35d4b890a58a877ca3865b0e6ca9be23f48e01d0a309ae75af4e702e8a68", + "sha256:dbc37d36c4e5fe502028525f77766a2e82ef1957a333b32765341be1a20c50a9", + "sha256:dc1c12c0567af7e7c56e01d7015f87489ea5a093d1e58177f5ca5a82981015b6", + "sha256:dc64e0823a32b0d4cb4fd25d6bbc9dd932352e9b5735773d220b705998d5efce", + "sha256:e228ce237fe511cb1b24b7a661f14e1b6c1af9255dbc40afcd28bab32da8ea09", + "sha256:ebd3471be2bf585fd3a3fe5fd940dc3439f680a8dfbd8e4393f16b296d95f19e", + "sha256:f23073e09738b2252191fbaf58f2b5485c2c7c0467f2637bd74252f60809d53f" ], "markers": "python_version >= '3.8'", - "version": "==8.7.1" + "version": "==8.10.1" }, "pillow": { "hashes": [ @@ -1236,19 +1266,19 @@ }, "prometheus-client": { "hashes": [ - "sha256:35f7a8c22139e2bb7ca5a698e92d38145bc8dc74c1c0bf56f25cca886a764e17", - "sha256:8de3ae2755f890826f4b6479e5571d4f74ac17a81345fe69a6778fdb92579184" + "sha256:4585b0d1223148c27a225b10dbec5ae9bc4c81a99a3fa80774fa6209935324e1", + "sha256:c88b1e6ecf6b41cd8fb5731c7ae919bf66df6ec6fafa555cd6c0e16ca169ae92" ], "markers": "python_version >= '3.8'", - "version": "==0.18.0" + "version": "==0.19.0" }, "prompt-toolkit": { "hashes": [ - "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0", - "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2" + "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d", + "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.0.41" + "version": "==3.0.43" }, "psycopg2": { "hashes": [ @@ -1305,20 +1335,20 @@ }, "python-gnupg": { "hashes": [ - "sha256:5674bad4e93876c0b0d3197e314d7f942d39018bf31e2b833f6788a6813c3fb8", - "sha256:bf9b2d9032ef38139b7d64184176cd0b293eaeae6e4f93f50e304c7051174482" + "sha256:01d8013931c9fa3f45824bbea7054c03d6e11f258a72e7e086e168dbcb91854c", + "sha256:72ce142af6da7f07e433fef148b445fb3e07854acd2f88739008838745c0e9f5" ], "index": "pypi", - "version": "==0.5.1" + "version": "==0.5.2" }, "python-ipware": { "hashes": [ - "sha256:802858aa13308d572876d1883edae0eae380fe70a51fdefcb46c8a2099240862", - "sha256:a52757123c718342f74b16ab2d9d4a531888d69d10b8197c073164635df0a13b" + "sha256:1992920ef553165dfa35e6ea5a90762f64f3b943cc22ee6b4ec02e2c86d31178", + "sha256:9ba4805152ebb85ad5b53797185cd1ce6231e1db60155834f326c8cd61e8af34" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.0.0" + "version": "==2.0.1" }, "python-magic": { "hashes": [ @@ -1604,11 +1634,11 @@ }, "reportlab": { "hashes": [ - "sha256:956d5874ee56e88753cf4c49452d6a7fa54a64e049a0382bd0c0b2013a26ef9a", - "sha256:967c77f00efd918cc231cf8b6d8f4e477dc973b5c16557e3bd18dfaeb5a70234" + "sha256:169945817a1a7759fb7b7dae528c2f8064fc21d16338d9b572ebdcb756740853", + "sha256:d00693de8ab8761b122e409de883ba976c24839f93867090c0d40b5d5906e847" ], "markers": "python_version >= '3.7' and python_version < '4'", - "version": "==4.0.7" + "version": "==4.0.8" }, "rich": { "hashes": [ @@ -1653,34 +1683,34 @@ }, "scipy": { "hashes": [ - "sha256:00f325434b6424952fbb636506f0567898dca7b0f7654d48f1c382ea338ce9a3", - "sha256:033c3fd95d55012dd1148b201b72ae854d5086d25e7c316ec9850de4fe776929", - "sha256:0d3a136ae1ff0883fffbb1b05b0b2fea251cb1046a5077d0b435a1839b3e52b7", - "sha256:15f237e890c24aef6891c7d008f9ff7e758c6ef39a2b5df264650eb7900403c0", - "sha256:370f569c57e1d888304052c18e58f4a927338eafdaef78613c685ca2ea0d1fa0", - "sha256:3e1a8a4657673bfae1e05e1e1d6e94b0cabe5ed0c7c144c8aa7b7dbb774ce5c1", - "sha256:4b4bb134c7aa457e26cc6ea482b016fef45db71417d55cc6d8f43d799cdf9ef2", - "sha256:5305792c7110e32ff155aed0df46aa60a60fc6e52cd4ee02cdeb67eaccd5356e", - "sha256:5664e364f90be8219283eeb844323ff8cd79d7acbd64e15eb9c46b9bc7f6a42a", - "sha256:5f290cf561a4b4edfe8d1001ee4be6da60c1c4ea712985b58bf6bc62badee221", - "sha256:74e89dc5e00201e71dd94f5f382ab1c6a9f3ff806c7d24e4e90928bb1aafb280", - "sha256:7abda0e62ef00cde826d441485e2e32fe737bdddee3324e35c0e01dee65e2a88", - "sha256:90271dbde4be191522b3903fc97334e3956d7cfb9cce3f0718d0ab4fd7d8bfd6", - "sha256:91770cb3b1e81ae19463b3c235bf1e0e330767dca9eb4cd73ba3ded6c4151e4d", - "sha256:925c6f09d0053b1c0f90b2d92d03b261e889b20d1c9b08a3a51f61afc5f58165", - "sha256:9885e3e4f13b2bd44aaf2a1a6390a11add9f48d5295f7a592393ceb8991577a3", - "sha256:9ea7f579182d83d00fed0e5c11a4aa5ffe01460444219dedc448a36adf0c3917", - "sha256:a63d1ec9cadecce838467ce0631c17c15c7197ae61e49429434ba01d618caa83", - "sha256:bae66a2d7d5768eaa33008fa5a974389f167183c87bf39160d3fefe6664f8ddc", - "sha256:bba4d955f54edd61899776bad459bf7326e14b9fa1c552181f0479cc60a568cd", - "sha256:c77da50c9a91e23beb63c2a711ef9e9ca9a2060442757dffee34ea41847d8156", - "sha256:d2f6dee6cbb0e263b8142ed587bc93e3ed5e777f1f75448d24fb923d9fd4dce6", - "sha256:dfcc1552add7cb7c13fb70efcb2389d0624d571aaf2c80b04117e2755a0c5d15", - "sha256:e04aa19acc324a1a076abb4035dabe9b64badb19f76ad9c798bde39d41025cdc", - "sha256:e1f97cd89c0fe1a0685f8f89d85fa305deb3067d0668151571ba50913e445820" + "sha256:00150c5eae7b610c32589dda259eacc7c4f1665aedf25d921907f4d08a951b1c", + "sha256:028eccd22e654b3ea01ee63705681ee79933652b2d8f873e7949898dda6d11b6", + "sha256:1b7c3dca977f30a739e0409fb001056484661cb2541a01aba0bb0029f7b68db8", + "sha256:2c6ff6ef9cc27f9b3db93a6f8b38f97387e6e0591600369a297a50a8e96e835d", + "sha256:36750b7733d960d7994888f0d148d31ea3017ac15eef664194b4ef68d36a4a97", + "sha256:530f9ad26440e85766509dbf78edcfe13ffd0ab7fec2560ee5c36ff74d6269ff", + "sha256:5e347b14fe01003d3b78e196e84bd3f48ffe4c8a7b8a1afbcb8f5505cb710993", + "sha256:6550466fbeec7453d7465e74d4f4b19f905642c89a7525571ee91dd7adabb5a3", + "sha256:6df1468153a31cf55ed5ed39647279beb9cfb5d3f84369453b49e4b8502394fd", + "sha256:6e619aba2df228a9b34718efb023966da781e89dd3d21637b27f2e54db0410d7", + "sha256:8fce70f39076a5aa62e92e69a7f62349f9574d8405c0a5de6ed3ef72de07f446", + "sha256:90a2b78e7f5733b9de748f589f09225013685f9b218275257f8a8168ededaeaa", + "sha256:91af76a68eeae0064887a48e25c4e616fa519fa0d38602eda7e0f97d65d57937", + "sha256:933baf588daa8dc9a92c20a0be32f56d43faf3d1a60ab11b3f08c356430f6e56", + "sha256:acf8ed278cc03f5aff035e69cb511741e0418681d25fbbb86ca65429c4f4d9cd", + "sha256:ad669df80528aeca5f557712102538f4f37e503f0c5b9541655016dd0932ca79", + "sha256:b030c6674b9230d37c5c60ab456e2cf12f6784596d15ce8da9365e70896effc4", + "sha256:b9999c008ccf00e8fbcce1236f85ade5c569d13144f77a1946bef8863e8f6eb4", + "sha256:bc9a714581f561af0848e6b69947fda0614915f072dfd14142ed1bfe1b806710", + "sha256:ce7fff2e23ab2cc81ff452a9444c215c28e6305f396b2ba88343a567feec9660", + "sha256:cf00bd2b1b0211888d4dc75656c0412213a8b25e80d73898083f402b50f47e41", + "sha256:d10e45a6c50211fe256da61a11c34927c68f277e03138777bdebedd933712fea", + "sha256:ee410e6de8f88fd5cf6eadd73c135020bfbbbdfcd0f6162c36a7638a1ea8cc65", + "sha256:f313b39a7e94f296025e3cffc2c567618174c0b1dde173960cf23808f9fae4be", + "sha256:f3cd9e7b3c2c1ec26364856f9fbe78695fe631150f94cd1c22228456404cf1ec" ], - "markers": "python_version < '3.13' and python_version >= '3.9'", - "version": "==1.11.3" + "markers": "python_version >= '3.9'", + "version": "==1.11.4" }, "setproctitle": { "hashes": [ @@ -1820,20 +1850,20 @@ }, "tornado": { "hashes": [ - "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f", - "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5", - "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d", - "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3", - "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2", - "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a", - "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16", - "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a", - "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17", - "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0", - "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe" + "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0", + "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63", + "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263", + "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052", + "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f", + "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee", + "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78", + "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579", + "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212", + "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e", + "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2" ], "markers": "python_version >= '3.8'", - "version": "==6.3.3" + "version": "==6.4" }, "tqdm": { "hashes": [ @@ -1846,11 +1876,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], - "markers": "python_version < '3.10'", - "version": "==4.8.0" + "markers": "python_version < '3.11'", + "version": "==4.9.0" }, "tzdata": { "hashes": [ @@ -2276,35 +2306,45 @@ }, "zxing-cpp": { "hashes": [ - "sha256:0a178683b66422ac01ae35f749d58c50b271f9ab18def1c286f5fc61bcf81fa7", - "sha256:26d27f61d627c06cc3e91b1ce816bd780c9227fd10b7ca961264f67bfb3bdf66", - "sha256:313bac052bd38bd2cedaa2610d880b3d62254dd6d8be01795559b73872c54ed0", - "sha256:4163d72975191d40c879bc130d5e8aa1eef5d5e6bfe820d94b5c9a2cb10d664e", - "sha256:4d9655c7d682ce252fe5c25f22c6fafe4c5ac493830fa8a2c062c85d061ce3b4", - "sha256:650d8f6731f11c04f4662a48f1efa9dc26c97bbdfa4f9b14b4683f43b7ccde4d", - "sha256:66d01d40bacc7e5b40e9fa474dab64f2e75a091c6e7c9d4a6b539b5a724127e3", - "sha256:7245e551fc30e9708c0fd0f4d0d15f29c0b85075d20c18ddc53b87956a469544", - "sha256:7a8a468b420bf391707431d5a0dd881cb41033ae15f87820d93d5707c7bc55bc", - "sha256:8397ce7e1a7a92cd8f0045a4c64e4fcd97f4aaa51441d27bcb76eeda0a1917bc", - "sha256:843f72a1f2a8c397b4d92f757488b03d8597031e907442382d5662fd96b0fd21", - "sha256:a54cd56c0898cb63a08517b7d630484690a9bad4da1e443aebe64b7077444d90", - "sha256:ab8fff5791e1d858390e45325500f6a17d5d3b6ac0237ae84ceda6f5b7a3685a", - "sha256:ba91ba2af0cc75c9e53bf95963f409c6fa26aa7df38469e2cdcb5b38a6c7c1c7", - "sha256:d7ba898e4f5ee9cd426d4271ff8b26911e3346b1cb4262f06fdc917e42b7c123", - "sha256:da081b763032b05326ddc53d3ad28a8b7603d662ccce2ff29fd204d587d3cac9" + "sha256:0bcd8855da4a9ef9e92799446353b5b8fa3eb5da21346089f0f09dcbb8bef1b6", + "sha256:11884ef9d1a61e47ad89836339da9e1040cb28b083fb37462bc58e8d46f135bc", + "sha256:177d5ed00c505e1728a90dc4742c6f0a4d9c2db56101809762f10f98fb822fa2", + "sha256:25d0dae34bdd8745103cd93c0cb315a0de4bb2876e564a35704be971ac07fcd4", + "sha256:3297daded419c87b2720ce9620817db4742814d7e31bfddeeb6329266a61f54f", + "sha256:4303e904a174df3c3f7f1817cf42a10521514865d9cdfcc9205e5ff0243c16fa", + "sha256:55a3f24aeb3e71a2090f3ded10d3b44865e60b640cebcb9c5f10e188158314ea", + "sha256:5e788ec26d10ac057f5027357ab404b1de2dd3ce216c1d0be20437dcd37f1afc", + "sha256:5e8bae00edea7f6350ced4f954ca2c3386afbf6d85d3303126f9cf8584cec454", + "sha256:70026b8370fc34c257fa76d84a07374a78a8a46cb00d36f285d32c60e9fbf6dd", + "sha256:70f9f13c4c91cb0747c0dc7ef247b39e19d38d07efd695fac17d11832f93d44a", + "sha256:7a7a616f6c8e02a92f8ab38d91bc14fecfbb3bc6bf2b69c4e5d7bb54eeaea141", + "sha256:7d620de9309d6f8d79dcb87b5c32bc8d72a1dbdc54369c31552a5ab277e25e78", + "sha256:7d9e7369bba46727e4a7fa1b5bd2b630696ec042df60063c13f2d844887950b1", + "sha256:8256ed05d0978e87847e91e2aff03b21c19cf4256dcb8af8a335de8361f027be", + "sha256:8602d7cad833007df497b8db7c1216fc7d21e077eb02206b45f4fc061b082913", + "sha256:92acc610eb6100cc5dd4c0f583de22e137c051a0f6e653dba6aef07e8c32810f", + "sha256:a16148c7a7926f2f897c69c695f4b334cd1a777bbfa0269204245fad288b47cf", + "sha256:a9868fbb9770ef2a2b72b6fe67d7528b9e4858ba6a130e59969ecb2e71271cd1", + "sha256:b69dcee874b59201a586e8fc77a7f83a92cd09d029d22a8b7b4f7112db2c675f", + "sha256:c0b35274af536ac9091d446ba0f69840feba62525feddf24b7b8991d924d6543", + "sha256:c2ff0059eef121ae7769ba4baeee52172438ca770cb4054e1d114beeda66226d", + "sha256:e2059fb6d47eb80122856d1524611339bffe27ad7e4cf59bdb6d642989e238b4", + "sha256:e3cdd28dd42176f59aa7fcbd052ec1d60c1fa29363b3fa5a8e41ecf8ce6e9be7", + "sha256:eb8ede507dad76d0ed606c17be943cfe554909cdb517f7650da076e8dc9648c0", + "sha256:f7d63385278ed2c674c756fe3448769b813351584e111cb61e6901a5e3dbf646" ], "markers": "platform_machine == 'x86_64' and python_version >= '3.6'", - "version": "==2.1.0" + "version": "==2.2.0" } }, "develop": { "anyio": { "hashes": [ - "sha256:56a415fbc462291813a94528a779597226619c8e78af7de0507333f700011e5f", - "sha256:5a0bec7085176715be77df87fc66d6c9d70626bd752fcc85f57cdbee5b3760da" + "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee", + "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "asgiref": { "hashes": [ @@ -2338,11 +2378,11 @@ }, "babel": { "hashes": [ - "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900", - "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed" + "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363", + "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287" ], "markers": "python_version >= '3.7'", - "version": "==2.13.1" + "version": "==2.14.0" }, "black": { "hashes": [ @@ -2568,90 +2608,90 @@ "toml" ], "hashes": [ - "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", - "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", - "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", - "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", - "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", - "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", - "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", - "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", - "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", - "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", - "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", - "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", - "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", - "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", - "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", - "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", - "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", - "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", - "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", - "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", - "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", - "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", - "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", - "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", - "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", - "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", - "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", - "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", - "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", - "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", - "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", - "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", - "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", - "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", - "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", - "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", - "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", - "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", - "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", - "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", - "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", - "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", - "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", - "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", - "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", - "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", - "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", - "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", - "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", - "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", - "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", - "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" + "sha256:007a7e49831cfe387473e92e9ff07377f6121120669ddc39674e7244350a6a29", + "sha256:1191270b06ecd68b1d00897b2daddb98e1719f63750969614ceb3438228c088e", + "sha256:1367aa411afb4431ab58fd7ee102adb2665894d047c490649e86219327183134", + "sha256:1f0f8f0c497eb9c9f18f21de0750c8d8b4b9c7000b43996a094290b59d0e7523", + "sha256:222b038f08a7ebed1e4e78ccf3c09a1ca4ac3da16de983e66520973443b546bc", + "sha256:243576944f7c1a1205e5cd658533a50eba662c74f9be4c050d51c69bd4532936", + "sha256:2e9223a18f51d00d3ce239c39fc41410489ec7a248a84fab443fbb39c943616c", + "sha256:307aecb65bb77cbfebf2eb6e12009e9034d050c6c69d8a5f3f737b329f4f15fb", + "sha256:31c0b1b8b5a4aebf8fcd227237fc4263aa7fa0ddcd4d288d42f50eff18b0bac4", + "sha256:3b15e03b8ee6a908db48eccf4e4e42397f146ab1e91c6324da44197a45cb9132", + "sha256:3c854c1d2c7d3e47f7120b560d1a30c1ca221e207439608d27bc4d08fd4aeae8", + "sha256:475de8213ed95a6b6283056d180b2442eee38d5948d735cd3d3b52b86dd65b92", + "sha256:50c472c1916540f8b2deef10cdc736cd2b3d1464d3945e4da0333862270dcb15", + "sha256:593efa42160c15c59ee9b66c5f27a453ed3968718e6e58431cdfb2d50d5ad284", + "sha256:65d716b736f16e250435473c5ca01285d73c29f20097decdbb12571d5dfb2c94", + "sha256:733537a182b5d62184f2a72796eb6901299898231a8e4f84c858c68684b25a70", + "sha256:757453848c18d7ab5d5b5f1827293d580f156f1c2c8cef45bfc21f37d8681069", + "sha256:79c32f875fd7c0ed8d642b221cf81feba98183d2ff14d1f37a1bbce6b0347d9f", + "sha256:7f3bad1a9313401ff2964e411ab7d57fb700a2d5478b727e13f156c8f89774a0", + "sha256:7fbf3f5756e7955174a31fb579307d69ffca91ad163467ed123858ce0f3fd4aa", + "sha256:811ca7373da32f1ccee2927dc27dc523462fd30674a80102f86c6753d6681bc6", + "sha256:89400aa1752e09f666cc48708eaa171eef0ebe3d5f74044b614729231763ae69", + "sha256:8c944cf1775235c0857829c275c777a2c3e33032e544bcef614036f337ac37bb", + "sha256:9437a4074b43c177c92c96d051957592afd85ba00d3e92002c8ef45ee75df438", + "sha256:9e17d9cb06c13b4f2ef570355fa45797d10f19ca71395910b249e3f77942a837", + "sha256:9ede881c7618f9cf93e2df0421ee127afdfd267d1b5d0c59bcea771cf160ea4a", + "sha256:a1f76cfc122c9e0f62dbe0460ec9cc7696fc9a0293931a33b8870f78cf83a327", + "sha256:a2ac4245f18057dfec3b0074c4eb366953bca6787f1ec397c004c78176a23d56", + "sha256:a702e66483b1fe602717020a0e90506e759c84a71dbc1616dd55d29d86a9b91f", + "sha256:ad2453b852a1316c8a103c9c970db8fbc262f4f6b930aa6c606df9b2766eee06", + "sha256:af75cf83c2d57717a8493ed2246d34b1f3398cb8a92b10fd7a1858cad8e78f59", + "sha256:afdcc10c01d0db217fc0a64f58c7edd635b8f27787fea0a3054b856a6dff8717", + "sha256:c59a3e59fb95e6d72e71dc915e6d7fa568863fad0a80b33bc7b82d6e9f844973", + "sha256:cad9afc1644b979211989ec3ff7d82110b2ed52995c2f7263e7841c846a75348", + "sha256:d299d379b676812e142fb57662a8d0d810b859421412b4d7af996154c00c31bb", + "sha256:d31650d313bd90d027f4be7663dfa2241079edd780b56ac416b56eebe0a21aab", + "sha256:d874434e0cb7b90f7af2b6e3309b0733cde8ec1476eb47db148ed7deeb2a9494", + "sha256:db0338c4b0951d93d547e0ff8d8ea340fecf5885f5b00b23be5aa99549e14cfd", + "sha256:df04c64e58df96b4427db8d0559e95e2df3138c9916c96f9f6a4dd220db2fdb7", + "sha256:e995efb191f04b01ced307dbd7407ebf6e6dc209b528d75583277b10fd1800ee", + "sha256:eda7f6e92358ac9e1717ce1f0377ed2b9320cea070906ece4e5c11d172a45a39", + "sha256:ee453085279df1bac0996bc97004771a4a052b1f1e23f6101213e3796ff3cb85", + "sha256:ee6621dccce8af666b8c4651f9f43467bfbf409607c604b840b78f4ff3619aeb", + "sha256:eee5e741b43ea1b49d98ab6e40f7e299e97715af2488d1c77a90de4a663a86e2", + "sha256:f3bfd2c2f0e5384276e12b14882bf2c7621f97c35320c3e7132c156ce18436a1", + "sha256:f501e36ac428c1b334c41e196ff6bd550c0353c7314716e80055b1f0a32ba394", + "sha256:f9191be7af41f0b54324ded600e8ddbcabea23e1e8ba419d9a53b241dece821d", + "sha256:fbd8a5fe6c893de21a3c6835071ec116d79334fbdf641743332e442a3466f7ea", + "sha256:fc200cec654311ca2c3f5ab3ce2220521b3d4732f68e1b1e79bef8fcfc1f2b97", + "sha256:ff4800783d85bff132f2cc7d007426ec698cdce08c3062c8d501ad3f4ea3d16c", + "sha256:ffb0eacbadb705c0a6969b0adf468f126b064f3362411df95f6d4f31c40d31c1", + "sha256:fff0b2f249ac642fd735f009b8363c2b46cf406d3caec00e4deeb79b5ff39b40" ], "markers": "python_version >= '3.8'", - "version": "==7.3.2" + "version": "==7.3.3" }, "cryptography": { "hashes": [ - "sha256:0c327cac00f082013c7c9fb6c46b7cc9fa3c288ca702c74773968173bda421bf", - "sha256:0d2a6a598847c46e3e321a7aef8af1436f11c27f1254933746304ff014664d84", - "sha256:227ec057cd32a41c6651701abc0328135e472ed450f47c2766f23267b792a88e", - "sha256:22892cc830d8b2c89ea60148227631bb96a7da0c1b722f2aac8824b1b7c0b6b8", - "sha256:392cb88b597247177172e02da6b7a63deeff1937fa6fec3bbf902ebd75d97ec7", - "sha256:3be3ca726e1572517d2bef99a818378bbcf7d7799d5372a46c79c29eb8d166c1", - "sha256:573eb7128cbca75f9157dcde974781209463ce56b5804983e11a1c462f0f4e88", - "sha256:580afc7b7216deeb87a098ef0674d6ee34ab55993140838b14c9b83312b37b86", - "sha256:5a70187954ba7292c7876734183e810b728b4f3965fbe571421cb2434d279179", - "sha256:73801ac9736741f220e20435f84ecec75ed70eda90f781a148f1bad546963d81", - "sha256:7d208c21e47940369accfc9e85f0de7693d9a5d843c2509b3846b2db170dfd20", - "sha256:8254962e6ba1f4d2090c44daf50a547cd5f0bf446dc658a8e5f8156cae0d8548", - "sha256:88417bff20162f635f24f849ab182b092697922088b477a7abd6664ddd82291d", - "sha256:a48e74dad1fb349f3dc1d449ed88e0017d792997a7ad2ec9587ed17405667e6d", - "sha256:b948e09fe5fb18517d99994184854ebd50b57248736fd4c720ad540560174ec5", - "sha256:c707f7afd813478e2019ae32a7c49cd932dd60ab2d2a93e796f68236b7e1fbf1", - "sha256:d38e6031e113b7421db1de0c1b1f7739564a88f1684c6b89234fbf6c11b75147", - "sha256:d3977f0e276f6f5bf245c403156673db103283266601405376f075c849a0b936", - "sha256:da6a0ff8f1016ccc7477e6339e1d50ce5f59b88905585f77193ebd5068f1e797", - "sha256:e270c04f4d9b5671ebcc792b3ba5d4488bf7c42c3c241a3748e2599776f29696", - "sha256:e886098619d3815e0ad5790c973afeee2c0e6e04b4da90b88e6bd06e2a0b1b72", - "sha256:ec3b055ff8f1dce8e6ef28f626e0972981475173d7973d63f271b29c8a2897da", - "sha256:fba1e91467c65fe64a82c689dc6cf58151158993b13eb7a7f3f4b7f395636723" + "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960", + "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a", + "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc", + "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a", + "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf", + "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1", + "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39", + "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406", + "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a", + "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a", + "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c", + "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be", + "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15", + "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2", + "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d", + "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157", + "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003", + "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248", + "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a", + "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec", + "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309", + "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7", + "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d" ], "markers": "python_version >= '3.7'", - "version": "==41.0.5" + "version": "==41.0.7" }, "daphne": { "hashes": [ @@ -2664,10 +2704,10 @@ }, "distlib": { "hashes": [ - "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057", - "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8" + "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784", + "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64" ], - "version": "==0.3.7" + "version": "==0.3.8" }, "exceptiongroup": { "hashes": [ @@ -2696,17 +2736,18 @@ }, "faker": { "hashes": [ - "sha256:171b27ba106cf69e30a91ac471407c2362bd6af27738e2461dc441aeff5eed91", - "sha256:df44b68b9d231e784f4bfe616d781576cfef9f0c5d9a17671bf84dc10d7b44d6" + "sha256:2d8a350e952225a145307d7461881c44a1c9320e90fbe8bd903d5947f133f3ec", + "sha256:ff61cca42547795bee8a11319792a8fee6d0f0cd191e831f7f3050c5851fcd8a" ], "markers": "python_version >= '3.8'", - "version": "==20.0.0" + "version": "==21.0.0" }, "filelock": { "hashes": [ "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e", "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c" ], + "index": "pypi", "markers": "python_version >= '3.8'", "version": "==3.13.1" }, @@ -2741,7 +2782,7 @@ "sha256:8b8fcaa0c8ea7b05edd69a094e63a2094c4efcb48129fb757361bc423c0ad9e8", "sha256:a05d3d052d9b2dfce0e3896636467f8a5342fb2b902c819428e1ac65413ca118" ], - "markers": "python_version >= '3.8'", + "markers": "python_version >= '3.9'", "version": "==0.25.2" }, "hyperlink": { @@ -3088,11 +3129,11 @@ }, "pyasn1": { "hashes": [ - "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57", - "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde" + "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58", + "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==0.5.0" + "version": "==0.5.1" }, "pyasn1-modules": { "hashes": [ @@ -3208,39 +3249,40 @@ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], + "index": "pypi", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.8.2" }, "pywavelets": { "hashes": [ - "sha256:030670a213ee8fefa56f6387b0c8e7d970c7f7ad6850dc048bd7c89364771b9b", - "sha256:058b46434eac4c04dd89aeef6fa39e4b6496a951d78c500b6641fd5b2cc2f9f4", - "sha256:231b0e0b1cdc1112f4af3c24eea7bf181c418d37922a67670e9bf6cfa2d544d4", - "sha256:23bafd60350b2b868076d976bdd92f950b3944f119b4754b1d7ff22b7acbf6c6", - "sha256:3f19327f2129fb7977bc59b966b4974dfd72879c093e44a7287500a7032695de", - "sha256:47cac4fa25bed76a45bc781a293c26ac63e8eaae9eb8f9be961758d22b58649c", - "sha256:578af438a02a86b70f1975b546f68aaaf38f28fb082a61ceb799816049ed18aa", - "sha256:6437af3ddf083118c26d8f97ab43b0724b956c9f958e9ea788659f6a2834ba93", - "sha256:64c6bac6204327321db30b775060fbe8e8642316e6bff17f06b9f34936f88875", - "sha256:67a0d28a08909f21400cb09ff62ba94c064882ffd9e3a6b27880a111211d59bd", - "sha256:71ab30f51ee4470741bb55fc6b197b4a2b612232e30f6ac069106f0156342356", - "sha256:7231461d7a8eb3bdc7aa2d97d9f67ea5a9f8902522818e7e2ead9c2b3408eeb1", - "sha256:754fa5085768227c4f4a26c1e0c78bc509a266d9ebd0eb69a278be7e3ece943c", - "sha256:7ab8d9db0fe549ab2ee0bea61f614e658dd2df419d5b75fba47baa761e95f8f2", - "sha256:875d4d620eee655346e3589a16a73790cf9f8917abba062234439b594e706784", - "sha256:88aa5449e109d8f5e7f0adef85f7f73b1ab086102865be64421a3a3d02d277f4", - "sha256:91d3d393cffa634f0e550d88c0e3f217c96cfb9e32781f2960876f1808d9b45b", - "sha256:9cb5ca8d11d3f98e89e65796a2125be98424d22e5ada360a0dbabff659fca0fc", - "sha256:ab7da0a17822cd2f6545626946d3b82d1a8e106afc4b50e3387719ba01c7b966", - "sha256:ad987748f60418d5f4138db89d82ba0cb49b086e0cbb8fd5c3ed4a814cfb705e", - "sha256:d0e56cd7a53aed3cceca91a04d62feb3a0aca6725b1912d29546c26f6ea90426", - "sha256:d854411eb5ee9cb4bc5d0e66e3634aeb8f594210f6a1bed96dbed57ec70f181c", - "sha256:da7b9c006171be1f9ddb12cc6e0d3d703b95f7f43cb5e2c6f5f15d3233fcf202", - "sha256:daf0aa79842b571308d7c31a9c43bc99a30b6328e6aea3f50388cd8f69ba7dbc", - "sha256:de7cd61a88a982edfec01ea755b0740e94766e00a1ceceeafef3ed4c85c605cd" + "sha256:00d5c37775a2baa4e5e6e9df3f93e6fc700a76bd50acd3b234bb13467cc54b6b", + "sha256:05723b35191ceb7d0c0bc2898a9ff391c0f20e8ed9b75d30211464872efcac95", + "sha256:2cae4a0151e443e915905c120435e69ad410b484ce8af4839220e43a494c7c53", + "sha256:322995ea0a57c96086782f0391934f9f00123087a62ad7bef0e778491f121931", + "sha256:34d189aed544687500a2fba5b8970951a76f62f1d140cc5f9440d9b32b14b8f5", + "sha256:49aa6abf9ac941f47f7ea26a3c7dd5c8bfcf0e903dc5ec68ed105b52bfccd4e2", + "sha256:4aca65696341aa64b98bf852d6768dbb345516710a2912419d68e9d484ddd6cd", + "sha256:4d9763987b4a79917f007c1d5df0adc81adabbad3c7c0a368f4a7f12034816f3", + "sha256:51c8e9e081af40f61d194960db0f3dc0434bbd979dafcbbd6463134b3f482f37", + "sha256:526e874ba79ee3779245737a3b8540defc7e92f6cec8f13258719cc1669f8b42", + "sha256:67b65da9ef6380a48b8b53de6d8a4f83747b84b217a37944a4dcf3a53cdf308d", + "sha256:7115439f0dff291b8f81b69caff1a240695566f17c483752a49de9576c7332a4", + "sha256:7a8b58eaf946fbee002cce460d32a0e932c6d9e158aad10eea984e7f26cda15e", + "sha256:7da6c2acd7253e5d45f371bcd6c0f34d70b2f82694420afb0631130bc89e3288", + "sha256:91847ac1b658cf985a7f91ff638ba1d4a9a0544c5480ecbf8db427baf455725a", + "sha256:9c3b10f1e1b08df4d918fa238ef5e5c51c111c4f6abdfecb19c26c540cbd8187", + "sha256:aa54e6c6f2d6953f5f962eb1d1de7f9fbc5bdf06141f58c05d0d87072a05b8be", + "sha256:c857081c037552f174732d864b55d8db4845f5e2fdf0e7bfc2df675a417906f4", + "sha256:ca2e1faaea7f7ff42c771e180635e2fb165cf23c9805c4fe05f9458bcb97d093", + "sha256:d7dc392c3d3d5415b25b5c6ab3b77bb2ac2b7ff6c4d2fb81bd4633b9ac4b66f3", + "sha256:d9e25c7cabef7ccd53f5fead26ab22152fe4cb937bad7411b5d506e2b5de38f6", + "sha256:e045ee612de58e3175ae863c34072b6bf5b45b61264c1adbd75506ce31cedbb2", + "sha256:eb123f01315c0fa54e25780f3b0ce0b096bab35f6c11cacbcd4ac9915f26508a", + "sha256:f3eba7f581a723132beb213ce4b291a51306e3d2f79241a71063294a71cfa25d", + "sha256:f457d9faee286bd542c8f1921e38b8f5f54bc1949c0e349c8f1e9f8eb6d251a6" ], - "markers": "python_version >= '3.8'", - "version": "==1.4.1" + "markers": "python_version >= '3.9'", + "version": "==1.5.0" }, "pyyaml": { "hashes": [ @@ -3295,7 +3337,6 @@ "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" ], - "markers": "python_version >= '3.6'", "version": "==6.0.1" }, "pyyaml-env-tag": { @@ -3410,58 +3451,58 @@ }, "ruff": { "hashes": [ - "sha256:0683b7bfbb95e6df3c7c04fe9d78f631f8e8ba4868dfc932d43d690698057e2e", - "sha256:1ea109bdb23c2a4413f397ebd8ac32cb498bee234d4191ae1a310af760e5d287", - "sha256:276a89bcb149b3d8c1b11d91aa81898fe698900ed553a08129b38d9d6570e717", - "sha256:290ecab680dce94affebefe0bbca2322a6277e83d4f29234627e0f8f6b4fa9ce", - "sha256:416dfd0bd45d1a2baa3b1b07b1b9758e7d993c256d3e51dc6e03a5e7901c7d80", - "sha256:45b38c3f8788a65e6a2cab02e0f7adfa88872696839d9882c13b7e2f35d64c5f", - "sha256:4af95fd1d3b001fc41325064336db36e3d27d2004cdb6d21fd617d45a172dd96", - "sha256:69a4bed13bc1d5dabf3902522b5a2aadfebe28226c6269694283c3b0cecb45fd", - "sha256:6b05e3b123f93bb4146a761b7a7d57af8cb7384ccb2502d29d736eaade0db519", - "sha256:6c64cb67b2025b1ac6d58e5ffca8f7b3f7fd921f35e78198411237e4f0db8e73", - "sha256:7f80496854fdc65b6659c271d2c26e90d4d401e6a4a31908e7e334fab4645aac", - "sha256:8b0c2de9dd9daf5e07624c24add25c3a490dbf74b0e9bca4145c632457b3b42a", - "sha256:90c958fe950735041f1c80d21b42184f1072cc3975d05e736e8d66fc377119ea", - "sha256:9dcc6bb2f4df59cb5b4b40ff14be7d57012179d69c6565c1da0d1f013d29951b", - "sha256:de02ca331f2143195a712983a57137c5ec0f10acc4aa81f7c1f86519e52b92a1", - "sha256:df2bb4bb6bbe921f6b4f5b6fdd8d8468c940731cb9406f274ae8c5ed7a78c478", - "sha256:dffd699d07abf54833e5f6cc50b85a6ff043715da8788c4a79bcd4ab4734d306" + "sha256:05ffe9dbd278965271252704eddb97b4384bf58b971054d517decfbf8c523f05", + "sha256:5daaeaf00ae3c1efec9742ff294b06c3a2a9db8d3db51ee4851c12ad385cda30", + "sha256:7d076717c67b34c162da7c1a5bda16ffc205e0e0072c03745275e7eab888719f", + "sha256:7de792582f6e490ae6aef36a58d85df9f7a0cfd1b0d4fe6b4fb51803a3ac96fa", + "sha256:a05b0ddd7ea25495e4115a43125e8a7ebed0aa043c3d432de7e7d6e8e8cd6448", + "sha256:aa8ee4f8440023b0a6c3707f76cadce8657553655dcbb5fc9b2f9bb9bee389f6", + "sha256:b6a21ab023124eafb7cef6d038f835cb1155cd5ea798edd8d9eb2f8b84be07d9", + "sha256:bd8ee69b02e7bdefe1e5da2d5b6eaaddcf4f90859f00281b2333c0e3a0cc9cd6", + "sha256:c8e3255afd186c142eef4ec400d7826134f028a85da2146102a1172ecc7c3696", + "sha256:ce697c463458555027dfb194cb96d26608abab920fa85213deb5edf26e026664", + "sha256:db6cedd9ffed55548ab313ad718bc34582d394e27a7875b4b952c2d29c001b26", + "sha256:e49fbdfe257fa41e5c9e13c79b9e79a23a79bd0e40b9314bc53840f520c2c0b3", + "sha256:e6f08ca730f4dc1b76b473bdf30b1b37d42da379202a059eae54ec7fc1fbcfed", + "sha256:f35960b02df6b827c1b903091bb14f4b003f6cf102705efc4ce78132a0aa5af3", + "sha256:f41f692f1691ad87f51708b823af4bb2c5c87c9248ddd3191c8f088e66ce590a", + "sha256:f7ee467677467526cfe135eab86a40a0e8db43117936ac4f9b469ce9cdb3fb62", + "sha256:ff78a7583020da124dd0deb835ece1d87bb91762d40c514ee9b67a087940528b" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.1.7" + "version": "==0.1.8" }, "scipy": { "hashes": [ - "sha256:00f325434b6424952fbb636506f0567898dca7b0f7654d48f1c382ea338ce9a3", - "sha256:033c3fd95d55012dd1148b201b72ae854d5086d25e7c316ec9850de4fe776929", - "sha256:0d3a136ae1ff0883fffbb1b05b0b2fea251cb1046a5077d0b435a1839b3e52b7", - "sha256:15f237e890c24aef6891c7d008f9ff7e758c6ef39a2b5df264650eb7900403c0", - "sha256:370f569c57e1d888304052c18e58f4a927338eafdaef78613c685ca2ea0d1fa0", - "sha256:3e1a8a4657673bfae1e05e1e1d6e94b0cabe5ed0c7c144c8aa7b7dbb774ce5c1", - "sha256:4b4bb134c7aa457e26cc6ea482b016fef45db71417d55cc6d8f43d799cdf9ef2", - "sha256:5305792c7110e32ff155aed0df46aa60a60fc6e52cd4ee02cdeb67eaccd5356e", - "sha256:5664e364f90be8219283eeb844323ff8cd79d7acbd64e15eb9c46b9bc7f6a42a", - "sha256:5f290cf561a4b4edfe8d1001ee4be6da60c1c4ea712985b58bf6bc62badee221", - "sha256:74e89dc5e00201e71dd94f5f382ab1c6a9f3ff806c7d24e4e90928bb1aafb280", - "sha256:7abda0e62ef00cde826d441485e2e32fe737bdddee3324e35c0e01dee65e2a88", - "sha256:90271dbde4be191522b3903fc97334e3956d7cfb9cce3f0718d0ab4fd7d8bfd6", - "sha256:91770cb3b1e81ae19463b3c235bf1e0e330767dca9eb4cd73ba3ded6c4151e4d", - "sha256:925c6f09d0053b1c0f90b2d92d03b261e889b20d1c9b08a3a51f61afc5f58165", - "sha256:9885e3e4f13b2bd44aaf2a1a6390a11add9f48d5295f7a592393ceb8991577a3", - "sha256:9ea7f579182d83d00fed0e5c11a4aa5ffe01460444219dedc448a36adf0c3917", - "sha256:a63d1ec9cadecce838467ce0631c17c15c7197ae61e49429434ba01d618caa83", - "sha256:bae66a2d7d5768eaa33008fa5a974389f167183c87bf39160d3fefe6664f8ddc", - "sha256:bba4d955f54edd61899776bad459bf7326e14b9fa1c552181f0479cc60a568cd", - "sha256:c77da50c9a91e23beb63c2a711ef9e9ca9a2060442757dffee34ea41847d8156", - "sha256:d2f6dee6cbb0e263b8142ed587bc93e3ed5e777f1f75448d24fb923d9fd4dce6", - "sha256:dfcc1552add7cb7c13fb70efcb2389d0624d571aaf2c80b04117e2755a0c5d15", - "sha256:e04aa19acc324a1a076abb4035dabe9b64badb19f76ad9c798bde39d41025cdc", - "sha256:e1f97cd89c0fe1a0685f8f89d85fa305deb3067d0668151571ba50913e445820" + "sha256:00150c5eae7b610c32589dda259eacc7c4f1665aedf25d921907f4d08a951b1c", + "sha256:028eccd22e654b3ea01ee63705681ee79933652b2d8f873e7949898dda6d11b6", + "sha256:1b7c3dca977f30a739e0409fb001056484661cb2541a01aba0bb0029f7b68db8", + "sha256:2c6ff6ef9cc27f9b3db93a6f8b38f97387e6e0591600369a297a50a8e96e835d", + "sha256:36750b7733d960d7994888f0d148d31ea3017ac15eef664194b4ef68d36a4a97", + "sha256:530f9ad26440e85766509dbf78edcfe13ffd0ab7fec2560ee5c36ff74d6269ff", + "sha256:5e347b14fe01003d3b78e196e84bd3f48ffe4c8a7b8a1afbcb8f5505cb710993", + "sha256:6550466fbeec7453d7465e74d4f4b19f905642c89a7525571ee91dd7adabb5a3", + "sha256:6df1468153a31cf55ed5ed39647279beb9cfb5d3f84369453b49e4b8502394fd", + "sha256:6e619aba2df228a9b34718efb023966da781e89dd3d21637b27f2e54db0410d7", + "sha256:8fce70f39076a5aa62e92e69a7f62349f9574d8405c0a5de6ed3ef72de07f446", + "sha256:90a2b78e7f5733b9de748f589f09225013685f9b218275257f8a8168ededaeaa", + "sha256:91af76a68eeae0064887a48e25c4e616fa519fa0d38602eda7e0f97d65d57937", + "sha256:933baf588daa8dc9a92c20a0be32f56d43faf3d1a60ab11b3f08c356430f6e56", + "sha256:acf8ed278cc03f5aff035e69cb511741e0418681d25fbbb86ca65429c4f4d9cd", + "sha256:ad669df80528aeca5f557712102538f4f37e503f0c5b9541655016dd0932ca79", + "sha256:b030c6674b9230d37c5c60ab456e2cf12f6784596d15ce8da9365e70896effc4", + "sha256:b9999c008ccf00e8fbcce1236f85ade5c569d13144f77a1946bef8863e8f6eb4", + "sha256:bc9a714581f561af0848e6b69947fda0614915f072dfd14142ed1bfe1b806710", + "sha256:ce7fff2e23ab2cc81ff452a9444c215c28e6305f396b2ba88343a567feec9660", + "sha256:cf00bd2b1b0211888d4dc75656c0412213a8b25e80d73898083f402b50f47e41", + "sha256:d10e45a6c50211fe256da61a11c34927c68f277e03138777bdebedd933712fea", + "sha256:ee410e6de8f88fd5cf6eadd73c135020bfbbbdfcd0f6162c36a7638a1ea8cc65", + "sha256:f313b39a7e94f296025e3cffc2c567618174c0b1dde173960cf23808f9fae4be", + "sha256:f3cd9e7b3c2c1ec26364856f9fbe78695fe631150f94cd1c22228456404cf1ec" ], - "markers": "python_version < '3.13' and python_version >= '3.9'", - "version": "==1.11.3" + "markers": "python_version >= '3.9'", + "version": "==1.11.4" }, "service-identity": { "hashes": [ @@ -3496,11 +3537,11 @@ }, "termcolor": { "hashes": [ - "sha256:3afb05607b89aed0ffe25202399ee0867ad4d3cb4180d98aaf8eefa6a5f7d475", - "sha256:b5b08f68937f138fe92f6c089b99f1e2da0ae56c52b78bf7075fd95420fd9a5a" + "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63", + "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a" ], - "markers": "python_version >= '3.7'", - "version": "==2.3.0" + "markers": "python_version >= '3.8'", + "version": "==2.4.0" }, "tomli": { "hashes": [ @@ -3531,11 +3572,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "markers": "python_version < '3.11'", - "version": "==4.8.0" + "version": "==4.9.0" }, "urllib3": { "hashes": [ @@ -3583,6 +3624,7 @@ "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44", "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33" ], + "index": "pypi", "markers": "python_version >= '3.7'", "version": "==3.0.0" }, @@ -3657,11 +3699,11 @@ }, "certifi": { "hashes": [ - "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", - "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" + "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", + "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" ], "markers": "python_version >= '3.6'", - "version": "==2023.7.22" + "version": "==2023.11.17" }, "cffi": { "hashes": [ @@ -3819,41 +3861,41 @@ }, "cryptography": { "hashes": [ - "sha256:0c327cac00f082013c7c9fb6c46b7cc9fa3c288ca702c74773968173bda421bf", - "sha256:0d2a6a598847c46e3e321a7aef8af1436f11c27f1254933746304ff014664d84", - "sha256:227ec057cd32a41c6651701abc0328135e472ed450f47c2766f23267b792a88e", - "sha256:22892cc830d8b2c89ea60148227631bb96a7da0c1b722f2aac8824b1b7c0b6b8", - "sha256:392cb88b597247177172e02da6b7a63deeff1937fa6fec3bbf902ebd75d97ec7", - "sha256:3be3ca726e1572517d2bef99a818378bbcf7d7799d5372a46c79c29eb8d166c1", - "sha256:573eb7128cbca75f9157dcde974781209463ce56b5804983e11a1c462f0f4e88", - "sha256:580afc7b7216deeb87a098ef0674d6ee34ab55993140838b14c9b83312b37b86", - "sha256:5a70187954ba7292c7876734183e810b728b4f3965fbe571421cb2434d279179", - "sha256:73801ac9736741f220e20435f84ecec75ed70eda90f781a148f1bad546963d81", - "sha256:7d208c21e47940369accfc9e85f0de7693d9a5d843c2509b3846b2db170dfd20", - "sha256:8254962e6ba1f4d2090c44daf50a547cd5f0bf446dc658a8e5f8156cae0d8548", - "sha256:88417bff20162f635f24f849ab182b092697922088b477a7abd6664ddd82291d", - "sha256:a48e74dad1fb349f3dc1d449ed88e0017d792997a7ad2ec9587ed17405667e6d", - "sha256:b948e09fe5fb18517d99994184854ebd50b57248736fd4c720ad540560174ec5", - "sha256:c707f7afd813478e2019ae32a7c49cd932dd60ab2d2a93e796f68236b7e1fbf1", - "sha256:d38e6031e113b7421db1de0c1b1f7739564a88f1684c6b89234fbf6c11b75147", - "sha256:d3977f0e276f6f5bf245c403156673db103283266601405376f075c849a0b936", - "sha256:da6a0ff8f1016ccc7477e6339e1d50ce5f59b88905585f77193ebd5068f1e797", - "sha256:e270c04f4d9b5671ebcc792b3ba5d4488bf7c42c3c241a3748e2599776f29696", - "sha256:e886098619d3815e0ad5790c973afeee2c0e6e04b4da90b88e6bd06e2a0b1b72", - "sha256:ec3b055ff8f1dce8e6ef28f626e0972981475173d7973d63f271b29c8a2897da", - "sha256:fba1e91467c65fe64a82c689dc6cf58151158993b13eb7a7f3f4b7f395636723" + "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960", + "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a", + "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc", + "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a", + "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf", + "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1", + "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39", + "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406", + "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a", + "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a", + "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c", + "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be", + "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15", + "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2", + "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d", + "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157", + "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003", + "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248", + "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a", + "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec", + "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309", + "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7", + "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d" ], "markers": "python_version >= '3.7'", - "version": "==41.0.5" + "version": "==41.0.7" }, "django": { "hashes": [ - "sha256:8e0f1c2c2786b5c0e39fe1afce24c926040fad47c8ea8ad30aaf1188df29fc41", - "sha256:e1d37c51ad26186de355cbcec16613ebdabfa9689bbade9c538835205a8abbe9" + "sha256:6cb5dcea9e3d12c47834d32156b8841f533a4493c688e2718cafd51aa430ba6d", + "sha256:d69d5e36cc5d9f4eb4872be36c622878afcdce94062716cf3e25bcedcb168b62" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.2.7" + "version": "==4.2.8" }, "django-filter-stubs": { "hashes": [ @@ -3868,72 +3910,72 @@ "compatible-mypy" ], "hashes": [ - "sha256:2fcd257884a68dfa02de41ee5410ec805264d9b07d9b5b119e4dea82c7b8345e", - "sha256:e60b43de662a199db4b15c803c06669e0ac5035614af291cbd3b91591f7dcc94" + "sha256:4cf4de258fa71adc6f2799e983091b9d46cfc67c6eebc68fe111218c9a62b3b8", + "sha256:8ccd2ff4ee5adf22b9e3b7b1a516d2e1c2191e9d94e672c35cc2bc3dd61e0f6b" ], "markers": "python_version >= '3.8'", - "version": "==4.2.6" + "version": "==4.2.7" }, "django-stubs-ext": { "hashes": [ - "sha256:8c4d1fb5f68419b3b2474c659681a189803e27d6a5e5abf5aa0da57601b58633", - "sha256:921cd7ae4614e74c234bc0fe86ee75537d163addfe1fc6f134bf03e29d86c01e" + "sha256:45a5d102417a412e3606e3c358adb4744988a92b7b58ccf3fd64bddd5d04d14c", + "sha256:519342ac0849cda1559746c9a563f03ff99f636b0ebe7c14b75e816a00dfddc3" ], "markers": "python_version >= '3.8'", - "version": "==4.2.5" + "version": "==4.2.7" }, "djangorestframework-stubs": { "extras": [ "compatible-mypy" ], "hashes": [ - "sha256:5be8275dd05d6629b3d1688929586ef7b6bc66b4f3f728b5e0389305f07c7a7f", - "sha256:8ee8719bfeb647b92cc200e15b3cc9813d2e4468c8190777a55a121542a4b2d4" + "sha256:43d788fd50cda49b922cd411e59c5b8cdc3f3de49c02febae12ce42139f0269b", + "sha256:5dd6f638aa5291fb7863e6166128a6ed20bf4986e2fc5cf334e6afc841797a09" ], "markers": "python_version >= '3.8'", - "version": "==3.14.4" + "version": "==3.14.5" }, "idna": { "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", + "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" ], "markers": "python_version >= '3.5'", - "version": "==3.4" + "version": "==3.6" }, "mypy": { "hashes": [ - "sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7", - "sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e", - "sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c", - "sha256:41697773aa0bf53ff917aa077e2cde7aa50254f28750f9b88884acea38a16169", - "sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208", - "sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0", - "sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1", - "sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1", - "sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7", - "sha256:68351911e85145f582b5aa6cd9ad666c8958bcae897a1bfda8f4940472463c45", - "sha256:7274b0c57737bd3476d2229c6389b2ec9eefeb090bbaf77777e9d6b1b5a9d143", - "sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5", - "sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f", - "sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd", - "sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245", - "sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f", - "sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332", - "sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30", - "sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183", - "sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f", - "sha256:bb8ccb4724f7d8601938571bf3f24da0da791fe2db7be3d9e79849cb64e0ae85", - "sha256:bbaf4662e498c8c2e352da5f5bca5ab29d378895fa2d980630656178bd607c46", - "sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71", - "sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660", - "sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb", - "sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c", - "sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a" + "sha256:12cce78e329838d70a204293e7b29af9faa3ab14899aec397798a4b41be7f340", + "sha256:1484b8fa2c10adf4474f016e09d7a159602f3239075c7bf9f1627f5acf40ad49", + "sha256:204e0d6de5fd2317394a4eff62065614c4892d5a4d1a7ee55b765d7a3d9e3f82", + "sha256:2643d145af5292ee956aa0a83c2ce1038a3bdb26e033dadeb2f7066fb0c9abce", + "sha256:2c6e4464ed5f01dc44dc9821caf67b60a4e5c3b04278286a85c067010653a0eb", + "sha256:2f7f6985d05a4e3ce8255396df363046c28bea790e40617654e91ed580ca7c51", + "sha256:31902408f4bf54108bbfb2e35369877c01c95adc6192958684473658c322c8a5", + "sha256:40716d1f821b89838589e5b3106ebbc23636ffdef5abc31f7cd0266db936067e", + "sha256:4b901927f16224d0d143b925ce9a4e6b3a758010673eeded9b748f250cf4e8f7", + "sha256:4fc3d14ee80cd22367caaaf6e014494415bf440980a3045bf5045b525680ac33", + "sha256:5cf3f0c5ac72139797953bd50bc6c95ac13075e62dbfcc923571180bebb662e9", + "sha256:6dbdec441c60699288adf051f51a5d512b0d818526d1dcfff5a41f8cd8b4aaf1", + "sha256:72cf32ce7dd3562373f78bd751f73c96cfb441de147cc2448a92c1a308bd0ca6", + "sha256:75aa828610b67462ffe3057d4d8a4112105ed211596b750b53cbfe182f44777a", + "sha256:75c4d2a6effd015786c87774e04331b6da863fc3fc4e8adfc3b40aa55ab516fe", + "sha256:78e25b2fd6cbb55ddfb8058417df193f0129cad5f4ee75d1502248e588d9e0d7", + "sha256:84860e06ba363d9c0eeabd45ac0fde4b903ad7aa4f93cd8b648385a888e23200", + "sha256:8c5091ebd294f7628eb25ea554852a52058ac81472c921150e3a61cdd68f75a7", + "sha256:944bdc21ebd620eafefc090cdf83158393ec2b1391578359776c00de00e8907a", + "sha256:9c7ac372232c928fff0645d85f273a726970c014749b924ce5710d7d89763a28", + "sha256:d9b338c19fa2412f76e17525c1b4f2c687a55b156320acb588df79f2e6fa9fea", + "sha256:ee5d62d28b854eb61889cde4e1dbc10fbaa5560cb39780c3995f6737f7e82120", + "sha256:f2c2521a8e4d6d769e3234350ba7b65ff5d527137cdcde13ff4d99114b0c8e7d", + "sha256:f6efc9bd72258f89a3816e3a98c09d36f079c223aa345c659622f056b760ab42", + "sha256:f7c5d642db47376a0cc130f0de6d055056e010debdaf0707cd2b0fc7e7ef30ea", + "sha256:fcb6d9afb1b6208b4c712af0dafdc650f518836065df0d4fb1d800f5d6773db2", + "sha256:fcd2572dd4519e8a6642b733cd3a8cfc1ef94bafd0c1ceed9c94fe736cb65b6a" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.6.1" + "version": "==1.7.1" }, "mypy-extensions": { "hashes": [ @@ -4008,11 +4050,11 @@ }, "types-markdown": { "hashes": [ - "sha256:816e19f03b08dcf74e8873080cccbc1577644940c49874ae5c2b89f400e149ac", - "sha256:c57ef7d510cb882ef0c1bfef3fc9401cfc329685eabdd9b15ce674f90ca6c546" + "sha256:2299b9086c695f408a3ebabf820f1fba3b239f1b3bfdbb32bf42d530b42cdd83", + "sha256:9afd38a8f53e19d43de3f8d89742b3674b5736767806ed9356d64ccb09f76439" ], "markers": "python_version >= '3.7'", - "version": "==3.5.0.1" + "version": "==3.5.0.3" }, "types-pillow": { "hashes": [ @@ -4024,20 +4066,20 @@ }, "types-psycopg2": { "hashes": [ - "sha256:cc80479def02e4dd1ef21649d82f04426c73bc0693bcc0a8b5223c7c168472af", - "sha256:cf99b62ab32cd4ef412fc3c4da1c29ca5a130847dff06d709b84a523802406f0" + "sha256:5b1e2e1d9478f8a298ea7038f8ea988e0ccc1f0af39f84636d57ef0da6f29e95", + "sha256:73baea689575bf5bb1b915b783fb0524044c6242928aeef1ae5a9e32f0780d3d" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.9.21.15" + "version": "==2.9.21.20" }, "types-pygments": { "hashes": [ - "sha256:26af0cc70fcc7b605d9af7c6c8dcbb5320bc4288e3dd1a3d590c8927e08299b6", - "sha256:33bc6574d4291e139ac2cc3627f6433aaa9c268e9543b5e1c42b5aa3060ba8d5" + "sha256:4241c5f1b7448e559cd820143a564cf10de626a95ab10e2daa463449d16864e7", + "sha256:83c33c89037f433fd5315b1abf80f5cb8b589b2d0549444d7f63824c628142c7" ], "markers": "python_version >= '3.7'", - "version": "==2.16.0.1" + "version": "==2.17.0.0" }, "types-pyopenssl": { "hashes": [ @@ -4071,12 +4113,12 @@ }, "types-redis": { "hashes": [ - "sha256:00f003da884ec3d1d54633186b4cbd587b39782595c5603330cc46a51f9bcf6e", - "sha256:aa7fb5f743534500f274ddf11ab1c910aae1020481865a36b799e1d67de2aaf3" + "sha256:94fc61118601fb4f79206b33b9f4344acff7ca1d7bba67834987fb0efcf6a770", + "sha256:c8cfc84635183deca2db4a528966c5566445fd3713983f0034fb0f5a09e0890d" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==4.6.0.10" + "version": "==4.6.0.11" }, "types-requests": { "hashes": [ @@ -4088,29 +4130,29 @@ }, "types-setuptools": { "hashes": [ - "sha256:8f31e8201e7969789e0eb23463b53ebe5f67d92417df4b648a6ea3c357ca4f51", - "sha256:e9c649559743e9f98c924bec91eae97f3ba208a70686182c3658fd7e81778d37" + "sha256:8c86195bae2ad81e6dea900a570fe9d64a59dbce2b11cc63c046b03246ea77bf", + "sha256:b0a06219f628c6527b2f8ce770a4f47550e00d3e8c3ad83e2dc31bc6e6eda95d" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==68.2.0.1" + "version": "==69.0.0.0" }, "types-tqdm": { "hashes": [ - "sha256:8eda4c5123dd66985a4cb44268705cfa18beb32d66772271ae185e92b8b10c40", - "sha256:a2f0ebd4cfd48f4914395819a176d7947387e1b98f9228fca38f8cac1b59891c" + "sha256:74bd7e469238c28816300f72a9b713d02036f6b557734616430adb7b7e74112c", + "sha256:d2c38085bec440e8ad1e94e8619f7cb3d1dd0a7ee06a863ccd0610a5945046ef" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==4.66.0.4" + "version": "==4.66.0.5" }, "typing-extensions": { "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "markers": "python_version < '3.11'", - "version": "==4.8.0" + "version": "==4.9.0" }, "urllib3": { "hashes": [ diff --git a/docs/administration.md b/docs/administration.md index 808d6afaf..cf8a24294 100644 --- a/docs/administration.md +++ b/docs/administration.md @@ -607,3 +607,10 @@ document_fuzzy_match [--ratio] [--processes N] | ----------- | -------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | --ratio | No | 85.0 | a number between 0 and 100, setting how similar a document must be for it to be reported. Higher numbers mean more similarity. | | --processes | No | 1/4 of system cores | Number of processes to use for matching. Setting 1 disables multiple processes | +| --delete | No | False | If provided, one document of a matched pair above the ratio will be deleted. | + +!!! warning + + If providing the `--delete` option, it is highly recommended to have a backup. + While every effort has been taken to ensure proper operation, there is always the + chance of deletion of a file you want to keep. diff --git a/docs/assets/screenshots/custom_field2.png b/docs/assets/screenshots/custom_field2.png index f7bf012dd..0bc2168a6 100644 Binary files a/docs/assets/screenshots/custom_field2.png and b/docs/assets/screenshots/custom_field2.png differ diff --git a/docs/assets/screenshots/editing.png b/docs/assets/screenshots/editing.png index e70b2891e..8026f6e05 100644 Binary files a/docs/assets/screenshots/editing.png and b/docs/assets/screenshots/editing.png differ diff --git a/docs/assets/screenshots/permissions_document.png b/docs/assets/screenshots/permissions_document.png index 9b05f104d..887cc2fc6 100644 Binary files a/docs/assets/screenshots/permissions_document.png and b/docs/assets/screenshots/permissions_document.png differ diff --git a/docs/changelog.md b/docs/changelog.md index 798387544..fc88e8110 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,38 @@ # Changelog +## paperless-ngx 2.1.2 + +### Bug Fixes + +- Fix: sort consumption templates by order by default [@shamoon](https://github.com/shamoon) ([#4956](https://github.com/paperless-ngx/paperless-ngx/pull/4956)) +- Fix: Updates gotenberg-client, including workaround for Gotenberg non-latin handling [@stumpylog](https://github.com/stumpylog) ([#4944](https://github.com/paperless-ngx/paperless-ngx/pull/4944)) +- Fix: allow text copy in pngx pdf viewer [@shamoon](https://github.com/shamoon) ([#4938](https://github.com/paperless-ngx/paperless-ngx/pull/4938)) +- Fix: Don't allow autocomplete searches to fail on schema field matches [@stumpylog](https://github.com/stumpylog) ([#4934](https://github.com/paperless-ngx/paperless-ngx/pull/4934)) +- Fix: Convert search dates to UTC in advanced search [@bogdal](https://github.com/bogdal) ([#4891](https://github.com/paperless-ngx/paperless-ngx/pull/4891)) +- Fix: Use the attachment filename so downstream template matching works [@stumpylog](https://github.com/stumpylog) ([#4931](https://github.com/paperless-ngx/paperless-ngx/pull/4931)) +- Fix: frontend handle autocomplete failure gracefully [@shamoon](https://github.com/shamoon) ([#4903](https://github.com/paperless-ngx/paperless-ngx/pull/4903)) + +### Dependencies + +- Chore(deps-dev): Bump the small-changes group with 2 updates [@dependabot](https://github.com/dependabot) ([#4942](https://github.com/paperless-ngx/paperless-ngx/pull/4942)) +- Chore(deps-dev): Bump the development group with 1 update [@dependabot](https://github.com/dependabot) ([#4939](https://github.com/paperless-ngx/paperless-ngx/pull/4939)) + +### All App Changes + +
+9 changes + +- Fix: sort consumption templates by order by default [@shamoon](https://github.com/shamoon) ([#4956](https://github.com/paperless-ngx/paperless-ngx/pull/4956)) +- Chore: reorganize api tests [@shamoon](https://github.com/shamoon) ([#4935](https://github.com/paperless-ngx/paperless-ngx/pull/4935)) +- Chore(deps-dev): Bump the small-changes group with 2 updates [@dependabot](https://github.com/dependabot) ([#4942](https://github.com/paperless-ngx/paperless-ngx/pull/4942)) +- Fix: allow text copy in pngx pdf viewer [@shamoon](https://github.com/shamoon) ([#4938](https://github.com/paperless-ngx/paperless-ngx/pull/4938)) +- Chore(deps-dev): Bump the development group with 1 update [@dependabot](https://github.com/dependabot) ([#4939](https://github.com/paperless-ngx/paperless-ngx/pull/4939)) +- Fix: Don't allow autocomplete searches to fail on schema field matches [@stumpylog](https://github.com/stumpylog) ([#4934](https://github.com/paperless-ngx/paperless-ngx/pull/4934)) +- Fix: Convert search dates to UTC in advanced search [@bogdal](https://github.com/bogdal) ([#4891](https://github.com/paperless-ngx/paperless-ngx/pull/4891)) +- Fix: Use the attachment filename so downstream template matching works [@stumpylog](https://github.com/stumpylog) ([#4931](https://github.com/paperless-ngx/paperless-ngx/pull/4931)) +- Fix: frontend handle autocomplete failure gracefully [@shamoon](https://github.com/shamoon) ([#4903](https://github.com/paperless-ngx/paperless-ngx/pull/4903)) +
+ ## paperless-ngx 2.1.1 ### Bug Fixes diff --git a/docs/usage.md b/docs/usage.md index fed7412b3..2412e3cbe 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -311,6 +311,8 @@ applied. You can use the following placeholders: - `{added_month_name}`: added month name - `{added_month_name_short}`: added month short name - `{added_day}`: added day +- `{added_time}`: added time in HH:MM format +- `{original_filename}`: original file name without extension ## Custom Fields {#custom-fields} diff --git a/src-ui/e2e/document-detail/document-detail.spec.ts b/src-ui/e2e/document-detail/document-detail.spec.ts index e40b88ccc..0cd45a058 100644 --- a/src-ui/e2e/document-detail/document-detail.spec.ts +++ b/src-ui/e2e/document-detail/document-detail.spec.ts @@ -12,13 +12,9 @@ test('should activate / deactivate save button when changes are saved', async ({ await expect(page.getByTitle('Storage path', { exact: true })).toHaveText( /\w+/ ) - await expect( - page.getByRole('button', { name: 'Save', exact: true }) - ).toBeDisabled() + await expect(page.getByRole('button', { name: 'Save' }).nth(1)).toBeDisabled() await page.getByTitle('Storage path').getByTitle('Clear all').click() - await expect( - page.getByRole('button', { name: 'Save', exact: true }) - ).toBeEnabled() + await expect(page.getByRole('button', { name: 'Save' }).nth(1)).toBeEnabled() }) test('should warn on unsaved changes', async ({ page }) => { @@ -27,16 +23,12 @@ test('should warn on unsaved changes', async ({ page }) => { await expect(page.getByTitle('Correspondent', { exact: true })).toHaveText( /\w+/ ) - await expect( - page.getByRole('button', { name: 'Save', exact: true }) - ).toBeDisabled() + await expect(page.getByRole('button', { name: 'Save' }).nth(1)).toBeDisabled() await page .getByTitle('Storage path', { exact: true }) .getByTitle('Clear all') .click() - await expect( - page.getByRole('button', { name: 'Save', exact: true }) - ).toBeEnabled() + await expect(page.getByRole('button', { name: 'Save' }).nth(1)).toBeEnabled() await page.getByRole('button', { name: 'Close', exact: true }).click() await expect(page.getByRole('dialog')).toHaveText(/unsaved changes/) await page.getByRole('button', { name: 'Cancel' }).click() diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index b16610851..2d8d57be5 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -236,6 +236,13 @@ 13 + + + + node_modules/src/ngb-config.ts + 13 + + Document was added to Paperless-ngx. @@ -255,7 +262,7 @@ src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 66 + 50 @@ -287,7 +294,7 @@ src/app/components/document-detail/document-detail.component.html - 96 + 92 @@ -396,11 +403,11 @@ src/app/components/app-frame/app-frame.component.html - 254 + 230 src/app/components/app-frame/app-frame.component.html - 257 + 233 @@ -418,15 +425,15 @@ Loading... src/app/components/admin/logs/logs.component.html - 20 + 16 src/app/components/admin/logs/logs.component.html - 32 + 25 src/app/components/admin/settings/settings.component.html - 325 + 312 src/app/components/admin/tasks/tasks.component.html @@ -434,55 +441,55 @@ src/app/components/admin/users-groups/users-groups.component.html - 102 + 96 src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 32 + 30 src/app/components/common/input/document-link/document-link.component.html - 44 + 40 src/app/components/common/permissions-dialog/permissions-dialog.component.html - 20 + 18 src/app/components/dashboard/dashboard.component.html - 15 + 14 src/app/components/dashboard/widgets/widget-frame/widget-frame.component.html - 16 + 14 src/app/components/document-detail/document-detail.component.html - 295 + 248 src/app/components/document-list/document-list.component.html - 105 + 95 src/app/components/manage/mail/mail.component.html - 113 + 104 src/app/components/manage/management-list/management-list.component.html - 55 + 52 src/app/components/manage/management-list/management-list.component.html - 55 + 52 src/app/components/manage/management-list/management-list.component.html - 55 + 52 src/app/components/manage/management-list/management-list.component.html - 55 + 52 @@ -493,19 +500,19 @@ src/app/components/admin/settings/settings.component.html - 284 + 274 src/app/components/app-frame/app-frame.component.html - 52 + 50 src/app/components/app-frame/app-frame.component.html - 228 + 208 src/app/components/app-frame/app-frame.component.html - 231 + 211 @@ -547,193 +554,193 @@ You need to reload the page after applying a new language. src/app/components/admin/settings/settings.component.html - 35 + 30 Date display src/app/components/admin/settings/settings.component.html - 43 + 37 Date format src/app/components/admin/settings/settings.component.html - 60 + 50 Short: src/app/components/admin/settings/settings.component.html - 66,67 + 56,57 Medium: src/app/components/admin/settings/settings.component.html - 70,71 + 60,61 Long: src/app/components/admin/settings/settings.component.html - 74,75 + 64,65 Items per page src/app/components/admin/settings/settings.component.html - 82 + 72 Document editor src/app/components/admin/settings/settings.component.html - 98 + 88 Use PDF viewer provided by the browser src/app/components/admin/settings/settings.component.html - 102 + 92 This is usually faster for displaying large PDF documents, but it might not work on some browsers. src/app/components/admin/settings/settings.component.html - 102 + 92 Sidebar src/app/components/admin/settings/settings.component.html - 109 + 99 Use 'slim' sidebar (icons only) src/app/components/admin/settings/settings.component.html - 113 + 103 Dark mode src/app/components/admin/settings/settings.component.html - 120 + 110 Use system settings src/app/components/admin/settings/settings.component.html - 123 + 113 Enable dark mode src/app/components/admin/settings/settings.component.html - 124 + 114 Invert thumbnails in dark mode src/app/components/admin/settings/settings.component.html - 125 + 115 Theme Color src/app/components/admin/settings/settings.component.html - 131 + 121 Reset src/app/components/admin/settings/settings.component.html - 140 + 130 Update checking src/app/components/admin/settings/settings.component.html - 145 + 135 Update checking works by pinging the public GitHub API for the latest release to determine whether a new version is available. Actual updating of the app must still be performed manually. src/app/components/admin/settings/settings.component.html - 149,152 + 139,142 No tracking data is collected by the app in any way. src/app/components/admin/settings/settings.component.html - 154,156 + 144,146 Enable update checking src/app/components/admin/settings/settings.component.html - 156 + 146 Bulk editing src/app/components/admin/settings/settings.component.html - 160 + 150 Show confirmation dialogs src/app/components/admin/settings/settings.component.html - 164 + 154 Deleting documents will always ask for confirmation. src/app/components/admin/settings/settings.component.html - 164 + 154 Apply on close src/app/components/admin/settings/settings.component.html - 165 + 155 Notes src/app/components/admin/settings/settings.component.html - 169 + 159 src/app/components/document-list/document-list.component.html - 187 + 164 src/app/services/rest/document.service.ts @@ -744,14 +751,14 @@ Enable notes src/app/components/admin/settings/settings.component.html - 173 + 163 Permissions src/app/components/admin/settings/settings.component.html - 181 + 171 src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.html @@ -767,7 +774,7 @@ src/app/components/document-detail/document-detail.component.html - 259 + 216 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -775,15 +782,15 @@ src/app/components/document-list/filter-editor/filter-editor.component.html - 84 + 76 src/app/components/manage/mail/mail.component.html - 38 + 37 src/app/components/manage/mail/mail.component.html - 91 + 86 src/app/components/manage/management-list/management-list.component.html @@ -806,50 +813,50 @@ Default Permissions src/app/components/admin/settings/settings.component.html - 184 + 174 Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI src/app/components/admin/settings/settings.component.html - 188,190 + 178,180 Default Owner src/app/components/admin/settings/settings.component.html - 195 + 185 Objects without an owner can be viewed and edited by all users src/app/components/admin/settings/settings.component.html - 199 + 189 src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 32 + 25 Default View Permissions src/app/components/admin/settings/settings.component.html - 204 + 194 Users: src/app/components/admin/settings/settings.component.html - 209 + 199 src/app/components/admin/settings/settings.component.html - 236 + 226 src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html @@ -861,22 +868,22 @@ src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 38 + 31 src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 57 + 50 Groups: src/app/components/admin/settings/settings.component.html - 219 + 209 src/app/components/admin/settings/settings.component.html - 246 + 236 src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html @@ -888,25 +895,25 @@ src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 46 + 39 src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 65 + 58 Default Edit Permissions src/app/components/admin/settings/settings.component.html - 231 + 221 Edit permissions also grant viewing permissions src/app/components/admin/settings/settings.component.html - 255 + 245 src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html @@ -914,92 +921,92 @@ src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 71 + 64 Notifications src/app/components/admin/settings/settings.component.html - 263 + 253 Document processing src/app/components/admin/settings/settings.component.html - 266 + 256 Show notifications when new documents are detected src/app/components/admin/settings/settings.component.html - 270 + 260 Show notifications when document processing completes successfully src/app/components/admin/settings/settings.component.html - 271 + 261 Show notifications when document processing fails src/app/components/admin/settings/settings.component.html - 272 + 262 Suppress notifications on dashboard src/app/components/admin/settings/settings.component.html - 273 + 263 This will suppress all messages about document processing status on the dashboard. src/app/components/admin/settings/settings.component.html - 273 + 263 Saved views src/app/components/admin/settings/settings.component.html - 281 + 271 src/app/components/app-frame/app-frame.component.html - 103 + 96 Show warning when closing saved views with unsaved changes src/app/components/admin/settings/settings.component.html - 287 + 277 Views src/app/components/admin/settings/settings.component.html - 291 + 281 src/app/components/document-list/document-list.component.html - 66 + 64 Name src/app/components/admin/settings/settings.component.html - 297 + 286 src/app/components/admin/tasks/tasks.component.html @@ -1011,7 +1018,7 @@ src/app/components/admin/users-groups/users-groups.component.html - 63 + 61 src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html @@ -1067,7 +1074,7 @@ src/app/components/manage/mail/mail.component.html - 70 + 66 src/app/components/manage/management-list/management-list.component.html @@ -1106,14 +1113,14 @@  Appears on src/app/components/admin/settings/settings.component.html - 301,302 + 291,292 Show on dashboard src/app/components/admin/settings/settings.component.html - 304 + 294 src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html @@ -1124,7 +1131,7 @@ Show in sidebar src/app/components/admin/settings/settings.component.html - 308 + 298 src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html @@ -1135,11 +1142,11 @@ Actions src/app/components/admin/settings/settings.component.html - 312 + 303 src/app/components/admin/tasks/tasks.component.html - 41 + 39 src/app/components/admin/users-groups/users-groups.component.html @@ -1147,11 +1154,11 @@ src/app/components/admin/users-groups/users-groups.component.html - 66 + 64 src/app/components/document-detail/document-detail.component.html - 49 + 45 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1171,30 +1178,30 @@ src/app/components/manage/mail/mail.component.html - 72 + 68 src/app/components/manage/management-list/management-list.component.html - 47 + 45 src/app/components/manage/management-list/management-list.component.html - 47 + 45 src/app/components/manage/management-list/management-list.component.html - 47 + 45 src/app/components/manage/management-list/management-list.component.html - 47 + 45 Delete src/app/components/admin/settings/settings.component.html - 313 + 304 src/app/components/admin/users-groups/users-groups.component.html @@ -1202,7 +1209,7 @@ src/app/components/admin/users-groups/users-groups.component.html - 85 + 83 src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts @@ -1214,63 +1221,63 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 44 + 33 src/app/components/document-detail/document-detail.component.html - 24 + 22 src/app/components/document-list/bulk-editor/bulk-editor.component.html - 142 + 138 src/app/components/manage/consumption-templates/consumption-templates.component.html - 37 + 36 src/app/components/manage/custom-fields/custom-fields.component.html - 35 + 34 src/app/components/manage/mail/mail.component.html - 43 + 42 src/app/components/manage/mail/mail.component.html - 96 + 91 src/app/components/manage/management-list/management-list.component.html - 90 + 80 src/app/components/manage/management-list/management-list.component.html - 90 + 80 src/app/components/manage/management-list/management-list.component.html - 90 + 80 src/app/components/manage/management-list/management-list.component.html - 90 + 80 src/app/components/manage/management-list/management-list.component.html - 108 + 98 src/app/components/manage/management-list/management-list.component.html - 108 + 98 src/app/components/manage/management-list/management-list.component.html - 108 + 98 src/app/components/manage/management-list/management-list.component.html - 108 + 98 src/app/components/manage/management-list/management-list.component.ts @@ -1281,30 +1288,30 @@ No saved views defined. src/app/components/admin/settings/settings.component.html - 319 + 308 Save src/app/components/admin/settings/settings.component.html - 337 + 323 src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 93 + 91 src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html - 25 + 21 src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html - 16 + 14 src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html - 27 + 23 src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.html @@ -1312,19 +1319,19 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 37 + 35 src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 49 + 43 src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html - 26 + 22 src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 28 + 24 src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html @@ -1332,36 +1339,22 @@ src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html - 58 + 54 src/app/components/document-detail/document-detail.component.html - 112 + 104 src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 21 - - - - Use system language - - src/app/components/admin/settings/settings.component.ts - 51 - - - - Use date format of display language - - src/app/components/admin/settings/settings.component.ts - 54 + 19 Error retrieving users src/app/components/admin/settings/settings.component.ts - 158 + 152 src/app/components/admin/users-groups/users-groups.component.ts @@ -1372,7 +1365,7 @@ Error retrieving groups src/app/components/admin/settings/settings.component.ts - 177 + 171 src/app/components/admin/users-groups/users-groups.component.ts @@ -1383,46 +1376,60 @@ Saved view "" deleted. src/app/components/admin/settings/settings.component.ts - 376 + 370 Settings were saved successfully. src/app/components/admin/settings/settings.component.ts - 498 + 492 Settings were saved successfully. Reload is required to apply some changes. src/app/components/admin/settings/settings.component.ts - 502 + 496 Reload now src/app/components/admin/settings/settings.component.ts - 503 + 497 An error occurred while saving settings. src/app/components/admin/settings/settings.component.ts - 513 + 507 src/app/components/app-frame/app-frame.component.ts 117 + + Use system language + + src/app/components/admin/settings/settings.component.ts + 515 + + + + Use date format of display language + + src/app/components/admin/settings/settings.component.ts + 522 + + Error while storing settings on server. src/app/components/admin/settings/settings.component.ts - 547 + 545 @@ -1433,7 +1440,7 @@ src/app/components/app-frame/app-frame.component.html - 242 + 222 @@ -1482,15 +1489,15 @@ src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 16 + 13 src/app/components/document-list/document-list.component.html - 209 + 185 src/app/components/document-list/filter-editor/filter-editor.component.html - 70 + 62 src/app/services/rest/document.service.ts @@ -1501,28 +1508,28 @@ Results src/app/components/admin/tasks/tasks.component.html - 38 + 37 Info src/app/components/admin/tasks/tasks.component.html - 40 + 38 click for full output src/app/components/admin/tasks/tasks.component.html - 71 + 61 Dismiss src/app/components/admin/tasks/tasks.component.html - 88 + 76 src/app/components/admin/tasks/tasks.component.ts @@ -1533,42 +1540,42 @@ Open Document src/app/components/admin/tasks/tasks.component.html - 95 + 82 {VAR_PLURAL, plural, =1 {One task} other { total tasks}} src/app/components/admin/tasks/tasks.component.html - 113 + 98 - - Failed + + Failed src/app/components/admin/tasks/tasks.component.html - 123,125 + 105 - - Complete + + Complete src/app/components/admin/tasks/tasks.component.html - 131,133 + 111 - - Started + + Started src/app/components/admin/tasks/tasks.component.html - 139,141 + 117 - - Queued + + Queued src/app/components/admin/tasks/tasks.component.html - 147,149 + 123 @@ -1635,11 +1642,11 @@ src/app/components/app-frame/app-frame.component.html - 235 + 215 src/app/components/app-frame/app-frame.component.html - 238 + 218 @@ -1650,7 +1657,7 @@ src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 78 + 68 @@ -1683,7 +1690,7 @@ src/app/components/admin/users-groups/users-groups.component.html - 51 + 50 src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html @@ -1698,85 +1705,85 @@ src/app/components/admin/users-groups/users-groups.component.html - 80 + 78 src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 53 + 46 src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 27 + 23 src/app/components/document-list/document-card-large/document-card-large.component.html - 61 + 49 src/app/components/document-list/document-card-small/document-card-small.component.html - 97 + 83 src/app/components/manage/consumption-templates/consumption-templates.component.html - 32 + 31 src/app/components/manage/custom-fields/custom-fields.component.html - 30 + 29 src/app/components/manage/mail/mail.component.html - 33 + 32 src/app/components/manage/mail/mail.component.html - 86 + 81 src/app/components/manage/management-list/management-list.component.html - 89 + 79 src/app/components/manage/management-list/management-list.component.html - 89 + 79 src/app/components/manage/management-list/management-list.component.html - 89 + 79 src/app/components/manage/management-list/management-list.component.html - 89 + 79 src/app/components/manage/management-list/management-list.component.html - 103 + 93 src/app/components/manage/management-list/management-list.component.html - 103 + 93 src/app/components/manage/management-list/management-list.component.html - 103 + 93 src/app/components/manage/management-list/management-list.component.html - 103 + 93 Add Group src/app/components/admin/users-groups/users-groups.component.html - 56 + 55 No groups defined src/app/components/admin/users-groups/users-groups.component.html - 93 + 89 @@ -1967,47 +1974,47 @@ Logged in as src/app/components/app-frame/app-frame.component.html - 41 + 39 My Profile src/app/components/app-frame/app-frame.component.html - 47 + 45 Logout src/app/components/app-frame/app-frame.component.html - 57 + 55 Documentation src/app/components/app-frame/app-frame.component.html - 63 + 61 src/app/components/app-frame/app-frame.component.html - 261 + 237 src/app/components/app-frame/app-frame.component.html - 264 + 240 Dashboard src/app/components/app-frame/app-frame.component.html - 86 + 80 src/app/components/app-frame/app-frame.component.html - 89 + 83 src/app/components/dashboard/dashboard.component.html @@ -2018,11 +2025,11 @@ Documents src/app/components/app-frame/app-frame.component.html - 93 + 87 src/app/components/app-frame/app-frame.component.html - 96 + 90 src/app/components/document-list/document-list.component.ts @@ -2030,70 +2037,70 @@ src/app/components/manage/management-list/management-list.component.html - 98 + 88 src/app/components/manage/management-list/management-list.component.html - 98 + 88 src/app/components/manage/management-list/management-list.component.html - 98 + 88 src/app/components/manage/management-list/management-list.component.html - 98 + 88 Open documents src/app/components/app-frame/app-frame.component.html - 138 + 123 Close all src/app/components/app-frame/app-frame.component.html - 158 + 139 src/app/components/app-frame/app-frame.component.html - 161 + 142 Manage src/app/components/app-frame/app-frame.component.html - 169 + 149 Correspondents src/app/components/app-frame/app-frame.component.html - 173 + 153 src/app/components/app-frame/app-frame.component.html - 176 + 156 src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 66 + 55 Tags src/app/components/app-frame/app-frame.component.html - 180 + 160 src/app/components/app-frame/app-frame.component.html - 183 + 163 src/app/components/common/input/tags/tags.component.ts @@ -2101,11 +2108,11 @@ src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 18 + 15 src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 58 + 49 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2113,48 +2120,48 @@ src/app/components/document-list/filter-editor/filter-editor.component.html - 34 + 26 Document Types src/app/components/app-frame/app-frame.component.html - 187 + 167 src/app/components/app-frame/app-frame.component.html - 190 + 170 src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 74 + 61 Storage Paths src/app/components/app-frame/app-frame.component.html - 194 + 174 src/app/components/app-frame/app-frame.component.html - 197 + 177 src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 82 + 67 Custom Fields src/app/components/app-frame/app-frame.component.html - 201 + 181 src/app/components/app-frame/app-frame.component.html - 204 + 184 src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.html @@ -2169,81 +2176,81 @@ Consumption templates src/app/components/app-frame/app-frame.component.html - 208 + 188 Templates src/app/components/app-frame/app-frame.component.html - 211 + 191 Mail src/app/components/app-frame/app-frame.component.html - 215 + 195 src/app/components/app-frame/app-frame.component.html - 218 + 198 Administration src/app/components/app-frame/app-frame.component.html - 224 + 204 - - File Tasks + + File Tasks src/app/components/app-frame/app-frame.component.html - 248,250 + 226 GitHub src/app/components/app-frame/app-frame.component.html - 270 + 246 is available. src/app/components/app-frame/app-frame.component.html - 277 + 252 Click to view. src/app/components/app-frame/app-frame.component.html - 277 + 252 Paperless-ngx can automatically check for updates src/app/components/app-frame/app-frame.component.html - 281 + 256 How does this work? src/app/components/app-frame/app-frame.component.html - 288,290 + 263,265 Update available src/app/components/app-frame/app-frame.component.html - 301 + 274 @@ -2271,22 +2278,22 @@ Clear src/app/components/common/clearable-badge/clearable-badge.component.html - 2 + 1 src/app/components/common/date-dropdown/date-dropdown.component.html - 38 + 33 src/app/components/common/date-dropdown/date-dropdown.component.html - 63 + 56 Cancel src/app/components/common/confirm-dialog/confirm-dialog.component.html - 16 + 12 @@ -2304,7 +2311,7 @@ src/app/components/common/permissions-dialog/permissions-dialog.component.html - 23 + 21 src/app/components/document-list/bulk-editor/bulk-editor.component.ts @@ -2381,21 +2388,21 @@ now src/app/components/common/date-dropdown/date-dropdown.component.html - 23 + 20 After src/app/components/common/date-dropdown/date-dropdown.component.html - 32 + 28 Before src/app/components/common/date-dropdown/date-dropdown.component.html - 57 + 51 @@ -2536,7 +2543,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 35 + 33 @@ -2547,7 +2554,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 38 + 35 @@ -2589,34 +2596,34 @@ Error src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 90 + 89 src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 46 + 41 src/app/components/common/toasts/toasts.component.html - 30 + 24 Cancel src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 92 + 90 src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html - 24 + 20 src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html - 15 + 13 src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html - 26 + 22 src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.html @@ -2624,19 +2631,19 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 36 + 34 src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 48 + 42 src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html - 25 + 21 src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 27 + 23 src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html @@ -2644,11 +2651,11 @@ src/app/components/common/permissions-dialog/permissions-dialog.component.html - 22 + 20 src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html - 57 + 53 src/app/components/common/select-dialog/select-dialog.component.html @@ -2660,7 +2667,7 @@ src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 20 + 18 @@ -2719,6 +2726,25 @@ Matching pattern + + src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 11 + + + src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html + 12 + + + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html + 12 + + + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html + 14 + + + + Case insensitive src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html 12 @@ -2736,25 +2762,6 @@ 15 - - Case insensitive - - src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html - 15 - - - src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html - 16 - - - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html - 16 - - - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 18 - - Create new correspondent @@ -2780,7 +2787,7 @@ Data type cannot be changed after a field is created src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html - 11 + 10 @@ -2900,7 +2907,7 @@ Test src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 34 + 32 @@ -2960,7 +2967,7 @@ src/app/components/manage/mail/mail.component.html - 71 + 67 @@ -3093,35 +3100,35 @@ Action parameter src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 30 + 29 Assignments specified here will supersede any consumption templates. src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 32 + 30 Assign title from src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 33 + 31 Assign correspondent from src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 36 + 34 Assign owner from rule src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 40 + 36 @@ -3404,11 +3411,11 @@ All src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 17 + 16 src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 20 + 18 src/app/components/common/permissions-select/permissions-select.component.html @@ -3427,35 +3434,35 @@ Any src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 19 + 18 Include src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 27 + 24 Exclude src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 29 + 26 Apply src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 51 + 42 Click again to exclude items. src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 59 + 48 @@ -3470,53 +3477,53 @@ Remove src/app/components/common/input/check/check.component.html - 10 + 8 src/app/components/common/input/date/date.component.html - 9 + 8 src/app/components/common/input/document-link/document-link.component.html - 11 + 8 src/app/components/common/input/number/number.component.html - 9 + 8 src/app/components/common/input/select/select.component.html - 11 + 8 src/app/components/common/input/text/text.component.html - 9 + 8 src/app/components/common/input/url/url.component.html - 9 + 8 Invalid date. src/app/components/common/input/date/date.component.html - 31 + 27 Suggestions: src/app/components/common/input/date/date.component.html - 37 + 30 src/app/components/common/input/select/select.component.html - 58 + 47 src/app/components/common/input/tags/tags.component.html - 57 + 46 @@ -3541,28 +3548,28 @@ Show password src/app/components/common/input/password/password.component.html - 6 + 5 Edit Permissions src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 9 + 7 Owner: src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 26 + 19 View src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 34 + 27 src/app/components/common/permissions-select/permissions-select.component.html @@ -3570,14 +3577,14 @@ src/app/components/document-list/document-card-large/document-card-large.component.html - 68 + 56 Add item src/app/components/common/input/select/select.component.html - 25 + 21 Used for both types, correspondents, storage paths @@ -3589,15 +3596,15 @@ src/app/components/common/tag/tag.component.html - 10 + 7 src/app/components/common/tag/tag.component.html - 13 + 8 src/app/components/document-list/document-card-small/document-card-small.component.ts - 80 + 77 @@ -3618,14 +3625,14 @@ Filter documents with these Tags src/app/components/common/input/tags/tags.component.html - 45 + 38 Open link src/app/components/common/input/url/url.component.html - 16 + 14 @@ -3653,28 +3660,28 @@ My documents src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 32 + 28 Shared with me src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 44 + 38 Unowned src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 56 + 48 Hide unowned src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 88 + 77 @@ -3698,6 +3705,13 @@ 61 + + Error loading preview + + src/app/components/common/preview-popup/preview-popup.component.html + 3 + + Edit Profile @@ -3734,36 +3748,36 @@ src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html - 43 + 39 src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 32 + 23 Regenerate auth token src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html - 45 + 41 Copied! src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html - 51 + 47 src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 47 + 36 Warning: changing the token cannot be undone src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html - 53 + 49 @@ -3838,35 +3852,35 @@ No existing links src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 11,13 + 10,12 Share src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 38 + 28 Share archive version src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 54 + 42 Expires src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 58 + 46 Create src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 73 + 55 @@ -3933,14 +3947,14 @@ Status src/app/components/common/toasts/toasts.component.html - 28 + 22 Copy Raw Error src/app/components/common/toasts/toasts.component.html - 44 + 33 @@ -3975,30 +3989,30 @@ Show all src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 9 + 8 src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 37 + 29 Title src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 17 + 14 src/app/components/document-detail/document-detail.component.html - 122 + 114 src/app/components/document-list/document-list.component.html - 172 + 150 src/app/components/document-list/filter-editor/filter-editor.component.ts - 108 + 203 src/app/services/rest/document.service.ts @@ -4009,11 +4023,11 @@ Correspondent src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 19 + 16 src/app/components/document-detail/document-detail.component.html - 126 + 118 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -4021,11 +4035,11 @@ src/app/components/document-list/document-list.component.html - 164 + 142 src/app/components/document-list/filter-editor/filter-editor.component.html - 43 + 35 src/app/services/rest/document.service.ts @@ -4036,37 +4050,37 @@ View Preview src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 39 + 31 Download src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 49 + 41 src/app/components/document-detail/document-detail.component.html - 31 + 29 src/app/components/document-list/bulk-editor/bulk-editor.component.html - 106 + 102 src/app/components/document-list/document-card-large/document-card-large.component.html - 76 + 64 src/app/components/document-list/document-card-small/document-card-small.component.html - 113 + 99 No documents src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 61 + 53 @@ -4080,35 +4094,35 @@ Go to inbox src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 5 + 4 Documents in inbox src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 6 + 5 Go to documents src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 10 + 8 Total documents src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 11 + 9 Total characters src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 15 + 13 @@ -4143,7 +4157,7 @@ Dismiss completed src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 16 + 13 This button dismisses all status messages about processed documents on the dashboard (failed and successful) @@ -4151,7 +4165,7 @@ {VAR_PLURAL, plural, =1 {One more document} other { more documents}} src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 35 + 27 This is shown as a summary line when there are more than 5 document in the processing pipeline. @@ -4259,21 +4273,21 @@ + src/app/components/document-detail/document-detail.component.html - 17 + 15 Download original src/app/components/document-detail/document-detail.component.html - 38 + 35 Redo OCR src/app/components/document-detail/document-detail.component.html - 55 + 51 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -4284,18 +4298,18 @@ More like this src/app/components/document-detail/document-detail.component.html - 61 + 57 src/app/components/document-list/document-card-large/document-card-large.component.html - 56 + 44 Close src/app/components/document-detail/document-detail.component.html - 86 + 82 src/app/guards/dirty-saved-view.guard.ts @@ -4306,56 +4320,56 @@ Previous src/app/components/document-detail/document-detail.component.html - 91 + 87 Discard src/app/components/document-detail/document-detail.component.html - 104 + 100 Save & next src/app/components/document-detail/document-detail.component.html - 107 + 102 Save & close src/app/components/document-detail/document-detail.component.html - 110 + 103 Details src/app/components/document-detail/document-detail.component.html - 119 + 111 Archive serial number src/app/components/document-detail/document-detail.component.html - 123 + 115 Date created src/app/components/document-detail/document-detail.component.html - 124 + 116 Document type src/app/components/document-detail/document-detail.component.html - 128 + 120 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -4363,11 +4377,11 @@ src/app/components/document-list/document-list.component.html - 195 + 171 src/app/components/document-list/filter-editor/filter-editor.component.html - 51 + 43 src/app/services/rest/document.service.ts @@ -4378,7 +4392,7 @@ Storage path src/app/components/document-detail/document-detail.component.html - 130 + 122 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -4386,32 +4400,32 @@ src/app/components/document-list/document-list.component.html - 202 + 178 src/app/components/document-list/filter-editor/filter-editor.component.html - 59 + 51 Default src/app/components/document-detail/document-detail.component.html - 131 + 123 Content src/app/components/document-detail/document-detail.component.html - 168 + 142 Metadata src/app/components/document-detail/document-detail.component.html - 177 + 151 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -4422,102 +4436,102 @@ Date modified src/app/components/document-detail/document-detail.component.html - 184 + 157 Date added src/app/components/document-detail/document-detail.component.html - 188 + 161 Media filename src/app/components/document-detail/document-detail.component.html - 192 + 165 Original filename src/app/components/document-detail/document-detail.component.html - 196 + 169 Original MD5 checksum src/app/components/document-detail/document-detail.component.html - 200 + 173 Original file size src/app/components/document-detail/document-detail.component.html - 204 + 177 Original mime type src/app/components/document-detail/document-detail.component.html - 208 + 181 Archive MD5 checksum src/app/components/document-detail/document-detail.component.html - 213 + 185 Archive file size src/app/components/document-detail/document-detail.component.html - 219 + 189 Original document metadata src/app/components/document-detail/document-detail.component.html - 228 + 195 Archived document metadata src/app/components/document-detail/document-detail.component.html - 231 + 196 Preview src/app/components/document-detail/document-detail.component.html - 238 + 202 - - Notes + + Notes src/app/components/document-detail/document-detail.component.html - 248,251 + 209,210 Enter Password src/app/components/document-detail/document-detail.component.html - 282 + 237 src/app/components/document-detail/document-detail.component.html - 324 + 275 @@ -4663,7 +4677,7 @@ src/app/components/document-list/filter-editor/filter-editor.component.html - 35 + 27 @@ -4674,7 +4688,7 @@ src/app/components/document-list/filter-editor/filter-editor.component.html - 44 + 36 @@ -4685,7 +4699,7 @@ src/app/components/document-list/filter-editor/filter-editor.component.html - 52 + 44 @@ -4696,35 +4710,35 @@ src/app/components/document-list/filter-editor/filter-editor.component.html - 60 + 52 Include: src/app/components/document-list/bulk-editor/bulk-editor.component.html - 112 + 108 Archived files src/app/components/document-list/bulk-editor/bulk-editor.component.html - 116,118 + 112,114 Original files src/app/components/document-list/bulk-editor/bulk-editor.component.html - 122,124 + 118,120 Use formatted filename src/app/components/document-list/bulk-editor/bulk-editor.component.html - 129,131 + 125,127 @@ -4906,126 +4920,126 @@ Filter by correspondent src/app/components/document-list/document-card-large/document-card-large.component.html - 21 + 20 src/app/components/document-list/document-list.component.html - 232 + 207 Filter by tag src/app/components/document-list/document-card-large/document-card-large.component.html - 29 + 24 src/app/components/document-list/document-list.component.html - 238 + 212 View notes src/app/components/document-list/document-card-large/document-card-large.component.html - 83 + 70 Notes src/app/components/document-list/document-card-large/document-card-large.component.html - 87 + 74 Filter by document type src/app/components/document-list/document-card-large/document-card-large.component.html - 91 + 76 src/app/components/document-list/document-list.component.html - 259 + 228 Filter by storage path src/app/components/document-list/document-card-large/document-card-large.component.html - 100 + 83 src/app/components/document-list/document-list.component.html - 264 + 233 Created: src/app/components/document-list/document-card-large/document-card-large.component.html - 118,119 + 98,99 src/app/components/document-list/document-card-small/document-card-small.component.html - 66,67 + 56,57 Added: src/app/components/document-list/document-card-large/document-card-large.component.html - 119,120 + 99,100 src/app/components/document-list/document-card-small/document-card-small.component.html - 67,68 + 57,58 Modified: src/app/components/document-list/document-card-large/document-card-large.component.html - 120,121 + 100,101 src/app/components/document-list/document-card-small/document-card-small.component.html - 68,69 + 58,59 Score: src/app/components/document-list/document-card-large/document-card-large.component.html - 139 + 116 Toggle tag filter src/app/components/document-list/document-card-small/document-card-small.component.html - 15 + 14 Toggle correspondent filter src/app/components/document-list/document-card-small/document-card-small.component.html - 38 + 32 Toggle document type filter src/app/components/document-list/document-card-small/document-card-small.component.html - 46 + 39 Toggle storage path filter src/app/components/document-list/document-card-small/document-card-small.component.html - 55 + 46 @@ -5060,71 +5074,71 @@ Save "" src/app/components/document-list/document-list.component.html - 85 + 76 Save as... src/app/components/document-list/document-list.component.html - 88 + 78 {VAR_PLURAL, plural, =1 {Selected of one document} other {Selected of documents}} src/app/components/document-list/document-list.component.html - 108 + 97 {VAR_PLURAL, plural, =1 {One document} other { documents}} src/app/components/document-list/document-list.component.html - 112 + 99 (filtered) src/app/components/document-list/document-list.component.html - 114 + 99 Reset filters src/app/components/document-list/document-list.component.html - 121 + 104 src/app/components/document-list/filter-editor/filter-editor.component.html - 92 + 84 Error while loading documents src/app/components/document-list/document-list.component.html - 137 + 117 Sort by ASN src/app/components/document-list/document-list.component.html - 153 + 131 ASN src/app/components/document-list/document-list.component.html - 157 + 135 src/app/components/document-list/filter-editor/filter-editor.component.ts - 113 + 208 src/app/services/rest/document.service.ts @@ -5135,28 +5149,28 @@ Sort by correspondent src/app/components/document-list/document-list.component.html - 160 + 138 Sort by title src/app/components/document-list/document-list.component.html - 167 + 145 Sort by owner src/app/components/document-list/document-list.component.html - 175 + 153 Owner src/app/components/document-list/document-list.component.html - 179 + 157 src/app/services/rest/document.service.ts @@ -5167,46 +5181,46 @@ Sort by notes src/app/components/document-list/document-list.component.html - 183 + 160 Sort by document type src/app/components/document-list/document-list.component.html - 191 + 167 Sort by storage path src/app/components/document-list/document-list.component.html - 198 + 174 Sort by created date src/app/components/document-list/document-list.component.html - 205 + 181 Sort by added date src/app/components/document-list/document-list.component.html - 212 + 188 Added src/app/components/document-list/document-list.component.html - 216 + 192 src/app/components/document-list/filter-editor/filter-editor.component.html - 76 + 68 src/app/services/rest/document.service.ts @@ -5217,7 +5231,7 @@ Edit document src/app/components/document-list/document-list.component.html - 236 + 211 @@ -5234,83 +5248,20 @@ 248 - - Title & content - - src/app/components/document-list/filter-editor/filter-editor.component.ts - 111 - - - - Custom fields - - src/app/components/document-list/filter-editor/filter-editor.component.ts - 116 - - - - Advanced search - - src/app/components/document-list/filter-editor/filter-editor.component.ts - 120 - - - - More like - - src/app/components/document-list/filter-editor/filter-editor.component.ts - 126 - - - - equals - - src/app/components/document-list/filter-editor/filter-editor.component.ts - 132 - - - - is empty - - src/app/components/document-list/filter-editor/filter-editor.component.ts - 136 - - - - is not empty - - src/app/components/document-list/filter-editor/filter-editor.component.ts - 140 - - - - greater than - - src/app/components/document-list/filter-editor/filter-editor.component.ts - 144 - - - - less than - - src/app/components/document-list/filter-editor/filter-editor.component.ts - 148 - - Correspondent: src/app/components/document-list/filter-editor/filter-editor.component.ts - 165,167 + 120,122 Without correspondent src/app/components/document-list/filter-editor/filter-editor.component.ts - 169 + 124 @@ -5319,14 +5270,14 @@ )?.name"/> src/app/components/document-list/filter-editor/filter-editor.component.ts - 175,177 + 130,132 Without document type src/app/components/document-list/filter-editor/filter-editor.component.ts - 179 + 134 @@ -5335,14 +5286,14 @@ )?.name"/> src/app/components/document-list/filter-editor/filter-editor.component.ts - 185,187 + 140,142 Without storage path src/app/components/document-list/filter-editor/filter-editor.component.ts - 189 + 144 @@ -5350,49 +5301,112 @@ ?.name"/> src/app/components/document-list/filter-editor/filter-editor.component.ts - 193,194 + 148,149 Without any tag src/app/components/document-list/filter-editor/filter-editor.component.ts - 198 + 153 Title: src/app/components/document-list/filter-editor/filter-editor.component.ts - 202 + 157 ASN: src/app/components/document-list/filter-editor/filter-editor.component.ts - 205 + 160 Owner: src/app/components/document-list/filter-editor/filter-editor.component.ts - 208 + 163 Owner not in: src/app/components/document-list/filter-editor/filter-editor.component.ts - 211 + 166 Without an owner src/app/components/document-list/filter-editor/filter-editor.component.ts - 214 + 169 + + + + Title & content + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 206 + + + + Custom fields + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 211 + + + + Advanced search + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 215 + + + + More like + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 221 + + + + equals + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 240 + + + + is empty + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 244 + + + + is not empty + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 248 + + + + greater than + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 252 + + + + less than + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 256 @@ -5406,46 +5420,46 @@ Filter rules error occurred while saving this view src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 13 + 12 The error returned was src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 14 + 13 Enter note src/app/components/document-notes/document-notes.component.html - 5 + 4 Please enter a note. src/app/components/document-notes/document-notes.component.html - 6,8 + 5,7 Add note src/app/components/document-notes/document-notes.component.html - 14 + 11 Delete note src/app/components/document-notes/document-notes.component.html - 25 + 21 src/app/components/document-notes/document-notes.component.html - 29 + 25 @@ -5501,7 +5515,7 @@ No templates defined. src/app/components/manage/consumption-templates/consumption-templates.component.html - 45 + 42 @@ -5592,7 +5606,7 @@ No fields defined. src/app/components/manage/custom-fields/custom-fields.component.html - 43 + 40 @@ -5676,28 +5690,28 @@ No mail accounts defined. src/app/components/manage/mail/mail.component.html - 51 + 48 Mail rules src/app/components/manage/mail/mail.component.html - 59 + 55 Add Rule src/app/components/manage/mail/mail.component.html - 64 + 60 No mail rules defined. src/app/components/manage/mail/mail.component.html - 104 + 97 @@ -5896,38 +5910,38 @@ Filter Documents src/app/components/manage/management-list/management-list.component.html - 88 + 78 src/app/components/manage/management-list/management-list.component.html - 88 + 78 src/app/components/manage/management-list/management-list.component.html - 88 + 78 src/app/components/manage/management-list/management-list.component.html - 88 + 78 {VAR_PLURAL, plural, =1 {One } other { total }} src/app/components/manage/management-list/management-list.component.html - 122 + 109 src/app/components/manage/management-list/management-list.component.html - 122 + 109 src/app/components/manage/management-list/management-list.component.html - 122 + 109 src/app/components/manage/management-list/management-list.component.html - 122 + 109 @@ -6460,245 +6474,245 @@ English (US) src/app/services/settings.service.ts - 44 + 157 Afrikaans src/app/services/settings.service.ts - 50 + 163 Arabic src/app/services/settings.service.ts - 56 + 169 Belarusian src/app/services/settings.service.ts - 62 + 175 Bulgarian src/app/services/settings.service.ts - 68 + 181 Catalan src/app/services/settings.service.ts - 74 + 187 Czech src/app/services/settings.service.ts - 80 + 193 Danish src/app/services/settings.service.ts - 86 + 199 German src/app/services/settings.service.ts - 92 + 205 Greek src/app/services/settings.service.ts - 98 + 211 English (GB) src/app/services/settings.service.ts - 104 + 217 Spanish src/app/services/settings.service.ts - 110 + 223 Finnish src/app/services/settings.service.ts - 116 + 229 French src/app/services/settings.service.ts - 122 + 235 Hungarian src/app/services/settings.service.ts - 128 + 241 Italian src/app/services/settings.service.ts - 134 + 247 Luxembourgish src/app/services/settings.service.ts - 140 + 253 Dutch src/app/services/settings.service.ts - 146 + 259 Norwegian src/app/services/settings.service.ts - 152 + 265 Polish src/app/services/settings.service.ts - 158 + 271 Portuguese (Brazil) src/app/services/settings.service.ts - 164 + 277 Portuguese src/app/services/settings.service.ts - 170 + 283 Romanian src/app/services/settings.service.ts - 176 + 289 Russian src/app/services/settings.service.ts - 182 + 295 Slovak src/app/services/settings.service.ts - 188 + 301 Slovenian src/app/services/settings.service.ts - 194 + 307 Serbian src/app/services/settings.service.ts - 200 + 313 Swedish src/app/services/settings.service.ts - 206 + 319 Turkish src/app/services/settings.service.ts - 212 + 325 Ukrainian src/app/services/settings.service.ts - 218 + 331 Chinese Simplified src/app/services/settings.service.ts - 224 + 337 ISO 8601 src/app/services/settings.service.ts - 232 + 354 Successfully completed one-time migratration of settings to the database! src/app/services/settings.service.ts - 472 + 473 Unable to migrate settings to the database, please try saving manually. src/app/services/settings.service.ts - 473 + 474 You can restart the tour from the settings page. src/app/services/settings.service.ts - 543 + 544 diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts index 6910061d2..c3b98549a 100644 --- a/src-ui/src/app/app.module.ts +++ b/src-ui/src/app/app.module.ts @@ -107,6 +107,7 @@ import { CustomFieldsDropdownComponent } from './components/common/custom-fields import { ProfileEditDialogComponent } from './components/common/profile-edit-dialog/profile-edit-dialog.component' import { PdfViewerComponent } from './components/common/pdf-viewer/pdf-viewer.component' import { DocumentLinkComponent } from './components/common/input/document-link/document-link.component' +import { PreviewPopupComponent } from './components/common/preview-popup/preview-popup.component' import localeAf from '@angular/common/locales/af' import localeAr from '@angular/common/locales/ar' @@ -261,6 +262,7 @@ function initializeApp(settings: SettingsService) { ProfileEditDialogComponent, PdfViewerComponent, DocumentLinkComponent, + PreviewPopupComponent, ], imports: [ BrowserModule, diff --git a/src-ui/src/app/components/common/input/date/date.component.spec.ts b/src-ui/src/app/components/common/input/date/date.component.spec.ts index 2b5467412..766d7fa02 100644 --- a/src-ui/src/app/components/common/input/date/date.component.spec.ts +++ b/src-ui/src/app/components/common/input/date/date.component.spec.ts @@ -81,6 +81,16 @@ describe('DateComponent', () => { expect(eventSpy).toHaveBeenCalled() }) + it('should show allow system keyboard events', () => { + let event: KeyboardEvent = new KeyboardEvent('keypress', { + key: '9', + altKey: true, + }) + let preventDefaultSpy = jest.spyOn(event, 'preventDefault') + input.dispatchEvent(event) + expect(preventDefaultSpy).not.toHaveBeenCalled() + }) + it('should support paste', () => { expect(component.value).toBeUndefined() const date = '5/4/20' @@ -99,5 +109,25 @@ describe('DateComponent', () => { event['clipboardData'] = clipboardData input.dispatchEvent(event) expect(component.value).toEqual({ day: 4, month: 5, year: 2020 }) + // coverage + window['clipboardData'] = { + getData: (type) => '', + } + component.onPaste(new Event('foo') as any) + }) + + it('should set filter button title', () => { + component.title = 'foo' + expect(component.filterButtonTitle).toEqual( + 'Filter documents with this foo' + ) + }) + + it('should emit date on filter', () => { + let dateReceived + component.value = '12/16/2023' + component.filterDocuments.subscribe((date) => (dateReceived = date)) + component.onFilterDocuments() + expect(dateReceived).toEqual([{ day: 16, month: 12, year: 2023 }]) }) }) diff --git a/src-ui/src/app/components/common/input/date/date.component.ts b/src-ui/src/app/components/common/input/date/date.component.ts index 36bbea57c..9d96379e3 100644 --- a/src-ui/src/app/components/common/input/date/date.component.ts +++ b/src-ui/src/app/components/common/input/date/date.component.ts @@ -90,7 +90,11 @@ export class DateComponent } onKeyPress(event: KeyboardEvent) { - if ('Enter' !== event.key && !/[0-9,\.\/-]+/.test(event.key)) { + if ( + 'Enter' !== event.key && + !(event.altKey || event.metaKey || event.ctrlKey) && + !/[0-9,\.\/-]+/.test(event.key) + ) { event.preventDefault() } } diff --git a/src-ui/src/app/components/common/input/document-link/document-link.component.scss b/src-ui/src/app/components/common/input/document-link/document-link.component.scss index bcaa4e849..51f6fa055 100644 --- a/src-ui/src/app/components/common/input/document-link/document-link.component.scss +++ b/src-ui/src/app/components/common/input/document-link/document-link.component.scss @@ -1,6 +1,10 @@ -::ng-deep .ng-select-container .ng-value-container .ng-value { - background-color: transparent !important; - border-color: transparent; +::ng-deep .ng-select-container .ng-value-container { + overflow: hidden; + + .ng-value { + background-color: transparent !important; + border-color: transparent; + } } .sidebaricon { @@ -9,6 +13,4 @@ .badge { font-size: .75rem; - // --bs-primary: var(--pngx-bg-alt); - // color: var(--pngx-primary-text-contrast); } diff --git a/src-ui/src/app/components/common/input/document-link/document-link.component.spec.ts b/src-ui/src/app/components/common/input/document-link/document-link.component.spec.ts index d1af7ab2f..e00460ec5 100644 --- a/src-ui/src/app/components/common/input/document-link/document-link.component.spec.ts +++ b/src-ui/src/app/components/common/input/document-link/document-link.component.spec.ts @@ -20,6 +20,10 @@ const documents = [ id: 12, title: 'Document 12 bar', }, + { + id: 16, + title: 'Document 16 bar', + }, { id: 23, title: 'Document 23 bar', @@ -48,10 +52,15 @@ describe('DocumentLinkComponent', () => { fixture.detectChanges() }) - it('should retrieve selected documents from APIs', () => { - const getSpy = jest.spyOn(documentService, 'getCachedMany') + it('should retrieve selected documents from API', () => { + const getSpy = jest.spyOn(documentService, 'getFew') getSpy.mockImplementation((ids) => { - return of(documents.filter((d) => ids.includes(d.id))) + const docs = documents.filter((d) => ids.includes(d.id)) + return of({ + count: docs.length, + all: docs.map((d) => d.id), + results: docs, + }) }) component.writeValue([1]) expect(getSpy).toHaveBeenCalled() @@ -85,12 +94,18 @@ describe('DocumentLinkComponent', () => { }) it('should load values correctly', () => { - jest.spyOn(documentService, 'getCachedMany').mockImplementation((ids) => { - return of(documents.filter((d) => ids.includes(d.id))) + const getSpy = jest.spyOn(documentService, 'getFew') + getSpy.mockImplementation((ids) => { + const docs = documents.filter((d) => ids.includes(d.id)) + return of({ + count: docs.length, + all: docs.map((d) => d.id), + results: docs, + }) }) component.writeValue([12, 23]) expect(component.value).toEqual([12, 23]) - expect(component.selectedDocuments).toEqual([documents[1], documents[2]]) + expect(component.selectedDocuments).toEqual([documents[1], documents[3]]) component.writeValue(null) expect(component.value).toEqual([]) expect(component.selectedDocuments).toEqual([]) @@ -100,9 +115,14 @@ describe('DocumentLinkComponent', () => { }) it('should support unselect', () => { - const getSpy = jest.spyOn(documentService, 'getCachedMany') + const getSpy = jest.spyOn(documentService, 'getFew') getSpy.mockImplementation((ids) => { - return of(documents.filter((d) => ids.includes(d.id))) + const docs = documents.filter((d) => ids.includes(d.id)) + return of({ + count: docs.length, + all: docs.map((d) => d.id), + results: docs, + }) }) component.writeValue([12, 23]) component.unselect({ id: 23 }) @@ -115,4 +135,26 @@ describe('DocumentLinkComponent', () => { expect(component.compareDocuments(documents[0], { id: 2 })).toBeFalsy() expect(component.trackByFn(documents[1])).toEqual(12) }) + + it('should not include the current document or already selected documents in results', () => { + let foundDocs + component.foundDocuments$.subscribe((found) => (foundDocs = found)) + component.parentDocumentID = 23 + component.selectedDocuments = [documents[2]] + const listSpy = jest.spyOn(documentService, 'listFiltered') + listSpy.mockImplementation( + (page, pageSize, sortField, sortReverse, filterRules, extraParams) => { + const docs = documents.filter((d) => + d.title.includes(filterRules[0].value) + ) + return of({ + count: docs.length, + results: docs, + all: docs.map((d) => d.id), + }) + } + ) + component.documentsInput$.next('bar') + expect(foundDocs).toEqual([documents[1]]) + }) }) diff --git a/src-ui/src/app/components/common/input/document-link/document-link.component.ts b/src-ui/src/app/components/common/input/document-link/document-link.component.ts index dd7118074..77a0fb99a 100644 --- a/src-ui/src/app/components/common/input/document-link/document-link.component.ts +++ b/src-ui/src/app/components/common/input/document-link/document-link.component.ts @@ -43,6 +43,9 @@ export class DocumentLinkComponent @Input() notFoundText: string = $localize`No documents found` + @Input() + parentDocumentID: number + constructor(private documentsService: DocumentService) { super() } @@ -58,11 +61,11 @@ export class DocumentLinkComponent } else { this.loading = true this.documentsService - .getCachedMany(documentIDs) + .getFew(documentIDs, { fields: 'id,title' }) .pipe(takeUntil(this.unsubscribeNotifier)) - .subscribe((documents) => { + .subscribe((documentResults) => { this.loading = false - this.selectedDocuments = documents + this.selectedDocuments = documentResults.results super.writeValue(documentIDs) }) } @@ -86,7 +89,13 @@ export class DocumentLinkComponent { truncate_content: true } ) .pipe( - map((results) => results.results), + map((results) => + results.results.filter( + (d) => + d.id !== this.parentDocumentID && + !this.selectedDocuments.find((sd) => sd.id === d.id) + ) + ), catchError(() => of([])), // empty on error tap(() => (this.loading = false)) ) diff --git a/src-ui/src/app/components/common/preview-popup/preview-popup.component.html b/src-ui/src/app/components/common/preview-popup/preview-popup.component.html new file mode 100644 index 000000000..71c3faf1b --- /dev/null +++ b/src-ui/src/app/components/common/preview-popup/preview-popup.component.html @@ -0,0 +1,22 @@ +
+
+

Error loading preview

+
+ + + +
+ + + +
+ + +
+
+
diff --git a/src-ui/src/app/components/common/preview-popup/preview-popup.component.scss b/src-ui/src/app/components/common/preview-popup/preview-popup.component.scss new file mode 100644 index 000000000..af8dc565a --- /dev/null +++ b/src-ui/src/app/components/common/preview-popup/preview-popup.component.scss @@ -0,0 +1,9 @@ +.preview-popup-container > * { + width: 30rem !important; + height: 22rem !important; + overflow-y: scroll; +} + +::ng-deep .popover.popover-preview { + max-width: 32rem; +} diff --git a/src-ui/src/app/components/common/preview-popup/preview-popup.component.spec.ts b/src-ui/src/app/components/common/preview-popup/preview-popup.component.spec.ts new file mode 100644 index 000000000..edcf63f51 --- /dev/null +++ b/src-ui/src/app/components/common/preview-popup/preview-popup.component.spec.ts @@ -0,0 +1,92 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing' + +import { PreviewPopupComponent } from './preview-popup.component' +import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component' +import { By } from '@angular/platform-browser' +import { SafeUrlPipe } from 'src/app/pipes/safeurl.pipe' +import { SettingsService } from 'src/app/services/settings.service' +import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings' +import { HttpClientTestingModule } from '@angular/common/http/testing' +import { DocumentService } from 'src/app/services/rest/document.service' + +const doc = { + id: 10, + title: 'Document 10', + content: 'Cupcake ipsum dolor sit amet ice cream.', + original_file_name: 'sample.pdf', +} + +describe('PreviewPopupComponent', () => { + let component: PreviewPopupComponent + let fixture: ComponentFixture + let settingsService: SettingsService + let documentService: DocumentService + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [PreviewPopupComponent, PdfViewerComponent, SafeUrlPipe], + imports: [HttpClientTestingModule], + }) + settingsService = TestBed.inject(SettingsService) + documentService = TestBed.inject(DocumentService) + jest + .spyOn(documentService, 'getPreviewUrl') + .mockImplementation((id) => doc.original_file_name) + fixture = TestBed.createComponent(PreviewPopupComponent) + component = fixture.componentInstance + component.document = doc + fixture.detectChanges() + }) + + it('should guess if file is pdf by file name', () => { + expect(component.isPdf).toBeTruthy() + component.document.archived_file_name = 'sample.pdf' + expect(component.isPdf).toBeTruthy() + component.document.archived_file_name = undefined + component.document.original_file_name = 'sample.txt' + expect(component.isPdf).toBeFalsy() + component.document.original_file_name = 'sample.pdf' + }) + + it('should return settings for native PDF viewer', () => { + settingsService.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, false) + expect(component.useNativePdfViewer).toBeFalsy() + settingsService.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, true) + expect(component.useNativePdfViewer).toBeTruthy() + }) + + it('should render object if native PDF viewer enabled', () => { + settingsService.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, true) + fixture.detectChanges() + expect(fixture.debugElement.query(By.css('object'))).not.toBeNull() + }) + + it('should render pngx viewer if native PDF viewer disabled', () => { + settingsService.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, false) + fixture.detectChanges() + expect(fixture.debugElement.query(By.css('object'))).toBeNull() + expect(fixture.debugElement.query(By.css('pngx-pdf-viewer'))).not.toBeNull() + }) + + it('should show lock icon on password error', () => { + settingsService.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, false) + component.onError({ name: 'PasswordException' }) + fixture.detectChanges() + expect(component.requiresPassword).toBeTruthy() + expect(fixture.debugElement.query(By.css('svg'))).not.toBeNull() + }) + + it('should fall back to object for non-pdf', () => { + component.document.original_file_name = 'sample.png' + fixture.detectChanges() + expect(fixture.debugElement.query(By.css('object'))).not.toBeNull() + }) + + it('should show message on error', () => { + component.onError({}) + fixture.detectChanges() + expect(fixture.debugElement.nativeElement.textContent).toContain( + 'Error loading preview' + ) + }) +}) diff --git a/src-ui/src/app/components/common/preview-popup/preview-popup.component.ts b/src-ui/src/app/components/common/preview-popup/preview-popup.component.ts new file mode 100644 index 000000000..014e31e8b --- /dev/null +++ b/src-ui/src/app/components/common/preview-popup/preview-popup.component.ts @@ -0,0 +1,52 @@ +import { Component, Input } from '@angular/core' +import { PaperlessDocument } from 'src/app/data/paperless-document' +import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings' +import { DocumentService } from 'src/app/services/rest/document.service' +import { SettingsService } from 'src/app/services/settings.service' + +@Component({ + selector: 'pngx-preview-popup', + templateUrl: './preview-popup.component.html', + styleUrls: ['./preview-popup.component.scss'], +}) +export class PreviewPopupComponent { + @Input() + document: PaperlessDocument + + error = false + + requiresPassword: boolean = false + + get renderAsObject(): boolean { + return (this.isPdf && this.useNativePdfViewer) || !this.isPdf + } + + get previewURL() { + return this.documentService.getPreviewUrl(this.document.id) + } + + get useNativePdfViewer(): boolean { + return this.settingsService.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER) + } + + get isPdf(): boolean { + // We dont have time to retrieve metadata, make a best guess by file name + return ( + this.document?.original_file_name?.endsWith('.pdf') || + this.document?.archived_file_name?.endsWith('.pdf') + ) + } + + constructor( + private settingsService: SettingsService, + private documentService: DocumentService + ) {} + + onError(event: any) { + if (event.name == 'PasswordException') { + this.requiresPassword = true + } else { + this.error = true + } + } +} diff --git a/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.spec.ts b/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.spec.ts index 0b300bd74..7dcda57a7 100644 --- a/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.spec.ts +++ b/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.spec.ts @@ -11,7 +11,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { NgbAccordionModule, NgbActiveModal, - NgbModal, NgbModalModule, } from '@ng-bootstrap/ng-bootstrap' import { HttpClientModule } from '@angular/common/http' diff --git a/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts b/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts index 19391ce28..d89d49829 100644 --- a/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts +++ b/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts @@ -130,7 +130,8 @@ export class ProfileEditDialogComponent implements OnInit, OnDestroy { } save(): void { - const passwordChanged = this.currentPassword !== this.newPassword + const passwordChanged = + this.newPassword && this.currentPassword !== this.newPassword const profile = Object.assign({}, this.form.value) this.networkActive = true this.profileService diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html index e510c0aa5..5c1eb6864 100644 --- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html +++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html @@ -3,63 +3,54 @@ [title]="savedView.name" [loading]="loading" [draggable]="savedView" - > +> - @if (documents.length) { - Show all - } + Show all - @if (documents.length) { - - - - - - - - - - - @for (doc of documents; track doc) { - - - - - - - } - -
CreatedTitleTagsCorrespondent
{{doc.created_date | customDate}} - {{doc.title | documentTitle}} - - @for (t of doc.tags$ | async; track t) { - - } - - @if (doc.correspondent !== null) { - {{(doc.correspondent$ | async)?.name}} - } - -
- } @else { + + + + + + + + + + + + + + + + + +
CreatedTitleTagsCorrespondent
{{doc.created_date | customDate}} + {{doc.title | documentTitle}} + + + + {{(doc.correspondent$ | async)?.name}} + +
+ +

No documents

- } - +
diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts index e4a3041fc..84d1fb654 100644 --- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts +++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts @@ -29,6 +29,7 @@ import { SavedViewWidgetComponent } from './saved-view-widget.component' import { By } from '@angular/platform-browser' import { SafeUrlPipe } from 'src/app/pipes/safeurl.pipe' import { DragDropModule } from '@angular/cdk/drag-drop' +import { PreviewPopupComponent } from 'src/app/components/common/preview-popup/preview-popup.component' const savedView: PaperlessSavedView = { id: 1, @@ -74,6 +75,7 @@ describe('SavedViewWidgetComponent', () => { CustomDatePipe, DocumentTitlePipe, SafeUrlPipe, + PreviewPopupComponent, ], providers: [ PermissionsGuard, @@ -137,15 +139,18 @@ describe('SavedViewWidgetComponent', () => { ) component.ngOnInit() fixture.detectChanges() - component.mouseEnterPreview(documentResults[0]) + component.mouseEnterPreviewButton(documentResults[0]) expect(component.popover.isOpen()).toBeTruthy() expect(component.popoverHidden).toBeTruthy() tick(600) expect(component.popoverHidden).toBeFalsy() - component.mouseLeaveCard() + component.maybeClosePopover() - component.mouseEnterPreview(documentResults[1]) + component.mouseEnterPreviewButton(documentResults[1]) tick(100) + component.mouseLeavePreviewButton() + component.mouseEnterPreview() + expect(component.popover.isOpen()).toBeTruthy() component.mouseLeavePreview() tick(600) expect(component.popover.isOpen()).toBeFalsy() diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts index 982aeebaa..601d9384e 100644 --- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts +++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts @@ -26,10 +26,7 @@ import { queryParamsFromFilterRules } from 'src/app/utils/query-params' @Component({ selector: 'pngx-saved-view-widget', templateUrl: './saved-view-widget.component.html', - styleUrls: [ - './saved-view-widget.component.scss', - '../../../document-list/popover-preview/popover-preview.scss', - ], + styleUrls: ['./saved-view-widget.component.scss'], }) export class SavedViewWidgetComponent extends ComponentWithPermissions @@ -121,8 +118,11 @@ export class SavedViewWidgetComponent return this.documentService.getDownloadUrl(document.id) } - mouseEnterPreview(doc: PaperlessDocument) { - this.popover = this.popovers.get(this.documents.indexOf(doc)) + mouseEnterPreviewButton(doc: PaperlessDocument) { + const newPopover = this.popovers.get(this.documents.indexOf(doc)) + if (this.popover !== newPopover && this.popover?.isOpen()) + this.popover.close() + this.popover = newPopover this.mouseOnPreview = true if (!this.popover.isOpen()) { // we're going to open but hide to pre-load content during hover delay @@ -139,12 +139,24 @@ export class SavedViewWidgetComponent } } - mouseLeavePreview() { - this.mouseOnPreview = false + mouseEnterPreview() { + this.mouseOnPreview = true } - mouseLeaveCard() { - this.popover?.close() + mouseLeavePreview() { + this.mouseOnPreview = false + this.maybeClosePopover() + } + + mouseLeavePreviewButton() { + this.mouseOnPreview = false + this.maybeClosePopover() + } + + maybeClosePopover() { + setTimeout(() => { + if (!this.mouseOnPreview) this.popover?.close() + }, 300) } getCorrespondentQueryParams(correspondentId: number): Params { diff --git a/src-ui/src/app/components/document-detail/document-detail.component.html b/src-ui/src/app/components/document-detail/document-detail.component.html index 72e1727c7..3211e60ed 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.html +++ b/src-ui/src/app/components/document-detail/document-detail.component.html @@ -1,47 +1,43 @@ - @if (getContentType() === 'application/pdf' && !useNativePdfViewer) { -
-
Page
- -
of {{previewNumPages}}
-
-
- - - -
- } + +
+
Page
+ +
of {{previewNumPages}}
+
+
+ + + +
+
-
- - - - Download + + + + Download - @if (metadata?.has_archive_version) { - +
+ -
+
- - -
-
+ + Redo OCR + - - + +
+ - -
+ + -
-
+ + -
+
+
-
+ + +
- - - + + +
-
- - - @if (hasNext()) { - - } - @if (!hasNext()) { - - } - - -
-
+ +
- -
+
- -
+ +
-
- - @if (renderAsPlainText) { -
- } - @if (requiresPassword) { -
-
- -
-
- } -
- -
- - - @if (!metadata) { -
-
-
- Loading... -
-
- } - @if (getContentType() === 'application/pdf') { - @if (!useNativePdfViewer ) { -
- - -
- } @else { - - } - } - @if (renderAsPlainText) { +
+ +
- } - @if (showPasswordField) { -
-
- -
-
- } - +
+
+
+ +
+
+
+ +
+ + +
+ + + + + + +
+
+ + +
+
+
+ Loading... +
+
+ +
+ + +
+ + + +
+ +
+
+
+
+ +
+
+
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.scss b/src-ui/src/app/components/document-detail/document-detail.component.scss index ba9b0a5ea..026969339 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.scss +++ b/src-ui/src/app/components/document-detail/document-detail.component.scss @@ -44,3 +44,17 @@ textarea.rtl { .input-group .btn-outline-secondary { border-color: var(--bs-border-color); } + +.btn-group .btn.order-0 { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-top-left-radius: var(--bs-border-radius-sm); + border-bottom-left-radius: var(--bs-border-radius-sm); +} + +.btn-group .btn.order-3 { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-right-radius: var(--bs-border-radius-sm); + border-bottom-right-radius: var(--bs-border-radius-sm); +} diff --git a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html index 6c11a3751..b59c934f2 100644 --- a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html +++ b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html @@ -16,35 +16,23 @@
- @if (document.correspondent) { - @if (clickCorrespondent.observers.length ) { - {{(document.correspondent$ | async)?.name}} - } @else { - {{(document.correspondent$ | async)?.name}} - } - : - } + + {{(document.correspondent$ | async)?.name}} + {{(document.correspondent$ | async)?.name}}: + {{document.title | documentTitle}} - @for (t of document.tags$ | async; track t) { - - } +

- @if (document.__search_hit__ && document.__search_hit__.highlights) { - - } - @for (highlight of searchNoteHighlights; track highlight) { - - - - - - - } - @if (!document.__search_hit__) { - {{contentTrimmed}} - } + + + + + + + + {{contentTrimmed}}

@@ -53,97 +41,85 @@ -  More like this - - - - -  Edit - - - - -  View - - - - - - - -  Download - - +  More like this + + + + +  Edit + + + + +  View + + + + + + + +  Download + + -
- @if (notesEnabled && document.notes.length) { - - } - @if (document.document_type) { - - } - @if (document.storage_path) { - - } - @if (document.archive_serial_number | isNumber) { -
- - #{{document.archive_serial_number}} -
- } - -
- Created: {{ document.created | customDate }} - Added: {{ document.added | customDate }} - Modified: {{ document.modified | customDate }} -
-
-
- - {{document.created_date | customDate:'mediumDate'}} -
- @if (document.owner && document.owner !== settingsService.currentUser.id) { -
- - {{document.owner | username}} -
- } - @if (document.__search_hit__?.score) { -
- Score: - -
- } -
- - +
+ + + +
+ + #{{document.archive_serial_number}} +
+ +
+ Created: {{ document.created | customDate }} + Added: {{ document.added | customDate }} + Modified: {{ document.modified | customDate }}
+
+
+ + {{document.created_date | customDate:'mediumDate'}} +
+
+ + {{document.owner | username}} +
+
+ Score: +
+ + + + + diff --git a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.spec.ts b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.spec.ts index 7b3d0a5bb..7bdd8422c 100644 --- a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.spec.ts +++ b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.spec.ts @@ -19,6 +19,7 @@ import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe' import { SafeUrlPipe } from 'src/app/pipes/safeurl.pipe' import { DocumentCardLargeComponent } from './document-card-large.component' import { IsNumberPipe } from 'src/app/pipes/is-number.pipe' +import { PreviewPopupComponent } from '../../common/preview-popup/preview-popup.component' const doc = { id: 10, @@ -50,6 +51,7 @@ describe('DocumentCardLargeComponent', () => { IfPermissionsDirective, SafeUrlPipe, IsNumberPipe, + PreviewPopupComponent, ], providers: [DatePipe], imports: [ diff --git a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.ts b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.ts index 1725e5795..deb855449 100644 --- a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.ts +++ b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.ts @@ -15,10 +15,7 @@ import { ComponentWithPermissions } from '../../with-permissions/with-permission @Component({ selector: 'pngx-document-card-large', templateUrl: './document-card-large.component.html', - styleUrls: [ - './document-card-large.component.scss', - '../popover-preview/popover-preview.scss', - ], + styleUrls: ['./document-card-large.component.scss'], }) export class DocumentCardLargeComponent extends ComponentWithPermissions { constructor( diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html index cb0d7f77f..0fb4c8d56 100644 --- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html +++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html @@ -108,7 +108,7 @@ - + diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.spec.ts b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.spec.ts index b4b5efe11..28db4502e 100644 --- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.spec.ts +++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.spec.ts @@ -22,6 +22,7 @@ import { By } from '@angular/platform-browser' import { TagComponent } from '../../common/tag/tag.component' import { PaperlessTag } from 'src/app/data/paperless-tag' import { IsNumberPipe } from 'src/app/pipes/is-number.pipe' +import { PreviewPopupComponent } from '../../common/preview-popup/preview-popup.component' const doc = { id: 10, @@ -64,6 +65,7 @@ describe('DocumentCardSmallComponent', () => { SafeUrlPipe, TagComponent, IsNumberPipe, + PreviewPopupComponent, ], providers: [DatePipe], imports: [ diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.ts b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.ts index 65ee5e6ad..41ef958fb 100644 --- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.ts +++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.ts @@ -16,10 +16,7 @@ import { ComponentWithPermissions } from '../../with-permissions/with-permission @Component({ selector: 'pngx-document-card-small', templateUrl: './document-card-small.component.html', - styleUrls: [ - './document-card-small.component.scss', - '../popover-preview/popover-preview.scss', - ], + styleUrls: ['./document-card-small.component.scss'], }) export class DocumentCardSmallComponent extends ComponentWithPermissions { constructor( diff --git a/src-ui/src/app/components/document-list/popover-preview/popover-preview.scss b/src-ui/src/app/components/document-list/popover-preview/popover-preview.scss deleted file mode 100644 index b51e2e66b..000000000 --- a/src-ui/src/app/components/document-list/popover-preview/popover-preview.scss +++ /dev/null @@ -1,22 +0,0 @@ -::ng-deep .popover.popover-preview { - max-width: 40rem; - - .preview { - min-width: 30rem; - min-height: 18rem; - max-height: 35rem; - overflow-y: scroll; - } - - .spinner-border { - position: absolute; - top: 4rem; - left: calc(50% - 0.5rem); - z-index: 0; - } -} - -::ng-deep .popover-hidden .popover { - opacity: 0; - pointer-events: none; -} diff --git a/src-ui/src/app/services/rest/abstract-paperless-service.spec.ts b/src-ui/src/app/services/rest/abstract-paperless-service.spec.ts index 92ff923f4..7b5254bfd 100644 --- a/src-ui/src/app/services/rest/abstract-paperless-service.spec.ts +++ b/src-ui/src/app/services/rest/abstract-paperless-service.spec.ts @@ -96,6 +96,21 @@ export const commonAbstractPaperlessServiceTests = (endpoint, ServiceClass) => { expect(req.request.method).toEqual('PATCH') req.flush([]) }) + + test('should call appropriate api endpoint for get a few objects', () => { + subscription = service.getFew([1, 2, 3]).subscribe() + const req = httpTestingController.expectOne( + `${environment.apiBaseUrl}${endpoint}/?id__in=1,2,3` + ) + expect(req.request.method).toEqual('GET') + req.flush([]) + subscription = service.getFew([4, 5, 6], { foo: 'bar' }).subscribe() + const req2 = httpTestingController.expectOne( + `${environment.apiBaseUrl}${endpoint}/?id__in=4,5,6&foo=bar` + ) + expect(req2.request.method).toEqual('GET') + req2.flush([]) + }) }) beforeEach(() => { diff --git a/src-ui/src/app/services/rest/abstract-paperless-service.ts b/src-ui/src/app/services/rest/abstract-paperless-service.ts index 14735b1ad..9305ed8b6 100644 --- a/src-ui/src/app/services/rest/abstract-paperless-service.ts +++ b/src-ui/src/app/services/rest/abstract-paperless-service.ts @@ -91,6 +91,19 @@ export abstract class AbstractPaperlessService { ) } + getFew(ids: number[], extraParams?): Observable> { + let httpParams = new HttpParams() + httpParams = httpParams.set('id__in', ids.join(',')) + for (let extraParamKey in extraParams) { + if (extraParams[extraParamKey] != null) { + httpParams = httpParams.set(extraParamKey, extraParams[extraParamKey]) + } + } + return this.http.get>(this.getResourceUrl(), { + params: httpParams, + }) + } + clearCache() { this._listAll = null } diff --git a/src-ui/src/environments/environment.prod.ts b/src-ui/src/environments/environment.prod.ts index a61dc40ee..0f4078ee9 100644 --- a/src-ui/src/environments/environment.prod.ts +++ b/src-ui/src/environments/environment.prod.ts @@ -5,7 +5,7 @@ export const environment = { apiBaseUrl: document.baseURI + 'api/', apiVersion: '3', appTitle: 'Paperless-ngx', - version: '2.1.2-dev', + version: '2.1.3-dev', webSocketHost: window.location.host, webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:', webSocketBaseUrl: base_url.pathname + 'ws/', diff --git a/src-ui/src/locale/messages.fr_FR.xlf b/src-ui/src/locale/messages.fr_FR.xlf index d8e7aea86..3f550be66 100644 --- a/src-ui/src/locale/messages.fr_FR.xlf +++ b/src-ui/src/locale/messages.fr_FR.xlf @@ -10,13 +10,13 @@ Fermer
- + HH node_modules/src/ngb-config.ts 13 - HH + HH Close @@ -100,13 +100,13 @@ Précédent - + MM node_modules/src/ngb-config.ts 13 - MM + MM » diff --git a/src-ui/src/locale/messages.hr_HR.xlf b/src-ui/src/locale/messages.hr_HR.xlf index 7f3b2061c..fbc08b75c 100644 --- a/src-ui/src/locale/messages.hr_HR.xlf +++ b/src-ui/src/locale/messages.hr_HR.xlf @@ -288,7 +288,7 @@ src/app/app.component.ts 90 - Document was added to Paperless-ngx. + Dokument je dodan u Paperless-ngx. Open document @@ -316,7 +316,7 @@ src/app/app.component.ts 120 - Document is being processed by Paperless-ngx. + Dokument je u fazi obrade. Prev @@ -476,7 +476,7 @@ src/app/components/admin/tasks/tasks.component.html 15 - Auto refresh + Automatsko osvježavanje Loading... @@ -596,7 +596,7 @@ src/app/components/admin/settings/settings.component.html 15 - General + Općenito Appearance @@ -916,7 +916,7 @@ src/app/components/admin/settings/settings.component.html 178,180 - Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI + Postavke ovog korisničkog računa za objekte (Oznake, Pravila za e-poštu, itd.) stvorene putem web sučelja Default Owner @@ -2074,7 +2074,7 @@ src/app/components/admin/users-groups/users-groups.component.ts 124 - Deleted user + Izbrisani korisnik Error deleting user. @@ -2479,7 +2479,7 @@ src/app/components/app-frame/app-frame.component.ts 276 - An error occurred while saving update checking settings. + Došlo je do pogreške prilikom spremanja postavki ažuriranja. Clear @@ -3039,7 +3039,7 @@ src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html 9 - Data type + Tip podataka Data type cannot be changed after a field is created @@ -3047,7 +3047,7 @@ src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html 10 - Data type cannot be changed after a field is created + Tip podataka ne može se promijeniti nakon što je polje stvoreno Create new custom field @@ -3175,7 +3175,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html 19 - Character Set + Skup znakova Test diff --git a/src-ui/src/locale/messages.ro_RO.xlf b/src-ui/src/locale/messages.ro_RO.xlf index 2e032d5ea..caa977f7a 100644 --- a/src-ui/src/locale/messages.ro_RO.xlf +++ b/src-ui/src/locale/messages.ro_RO.xlf @@ -16,7 +16,7 @@ node_modules/src/ngb-config.ts 13 - HH + HH Close @@ -44,7 +44,7 @@ node_modules/src/ngb-config.ts 13 - Select month + Selectați luna Previous month @@ -56,7 +56,7 @@ node_modules/src/ngb-config.ts 13 - Previous month + Luna precedentă @@ -82,7 +82,7 @@ node_modules/src/ngb-config.ts 13 - Hours + Ore « @@ -98,7 +98,7 @@ node_modules/src/ngb-config.ts 13 - Previous + Anterior MM @@ -106,7 +106,7 @@ node_modules/src/ngb-config.ts 13 - MM + MM » @@ -126,7 +126,7 @@ node_modules/src/ngb-config.ts 13 - Select year + Selectați anul Next month @@ -138,7 +138,7 @@ node_modules/src/ngb-config.ts 13 - Next month + Luna următoare Next @@ -146,7 +146,7 @@ node_modules/src/ngb-config.ts 13 - Next + Următor Minutes @@ -154,7 +154,7 @@ node_modules/src/ngb-config.ts 13 - Minutes + Minute »» @@ -170,7 +170,7 @@ node_modules/src/ngb-config.ts 13 - Increment hours + Incrementare ore First @@ -178,7 +178,7 @@ node_modules/src/ngb-config.ts 13 - First + Primul Previous @@ -186,7 +186,7 @@ node_modules/src/ngb-config.ts 13 - Previous + Anteriorul Decrement hours @@ -194,7 +194,7 @@ node_modules/src/ngb-config.ts 13 - Decrement hours + Decrementare oră Next @@ -202,7 +202,7 @@ node_modules/src/ngb-config.ts 13 - Next + Următor Increment minutes @@ -210,7 +210,7 @@ node_modules/src/ngb-config.ts 13 - Increment minutes + Incrementare minute Last @@ -218,7 +218,7 @@ node_modules/src/ngb-config.ts 13 - Last + Ultima Decrement minutes @@ -226,7 +226,7 @@ node_modules/src/ngb-config.ts 13 - Decrement minutes + Decrementare minute SS @@ -234,7 +234,7 @@ node_modules/src/ngb-config.ts 13 - SS + SS Seconds @@ -242,7 +242,7 @@ node_modules/src/ngb-config.ts 13 - Seconds + Secunde Increment seconds @@ -250,7 +250,7 @@ node_modules/src/ngb-config.ts 13 - Increment seconds + Incrementare secunde Decrement seconds @@ -258,7 +258,7 @@ node_modules/src/ngb-config.ts 13 - Decrement seconds + Decrementare secunde @@ -288,7 +288,7 @@ src/app/app.component.ts 90 - Document was added to Paperless-ngx. + Documentul a fost adăugat în sistem. Open document @@ -316,7 +316,7 @@ src/app/app.component.ts 120 - Document is being processed by Paperless-ngx. + Documentul este procesat de către sistem. Prev @@ -324,7 +324,7 @@ src/app/app.component.ts 126 - Prev + Anterior Next @@ -336,7 +336,7 @@ src/app/components/document-detail/document-detail.component.html 92 - Next + Următor End @@ -344,7 +344,7 @@ src/app/app.component.ts 128 - End + Sfârșit The dashboard can be used to show saved views, such as an 'Inbox'. Those settings are found under Settings > Saved Views once you have created some. @@ -352,7 +352,7 @@ src/app/app.component.ts 134 - The dashboard can be used to show saved views, such as an 'Inbox'. Those settings are found under Settings > Saved Views once you have created some. + Tabloul de bord poate fi folosit pentru a afișa vizualizările salvate, cum ar fi un 'Inbox'. Aceste setări sunt găsite în Setările > Vizualizări salvate după ce aţi creat unele. Drag-and-drop documents here to start uploading or place them in the consume folder. You can also drag-and-drop documents anywhere on all other pages of the web app. Once you do, Paperless-ngx will start training its machine learning algorithms. @@ -360,7 +360,7 @@ src/app/app.component.ts 141 - Drag-and-drop documents here to start uploading or place them in the consume folder. You can also drag-and-drop documents anywhere on all other pages of the web app. Once you do, Paperless-ngx will start training its machine learning algorithms. + Drag-and-drop documente aici pentru a începe încărcarea sau plasarea lor în folderul de consum. De asemenea, puteți trage și plasa documente oriunde pe toate celelalte pagini ale aplicației web. Odată ce faceți acest lucru, sistemul va începe să își instruiască algoritmii de învățare a mașinilor. The documents list shows all of your documents and allows for filtering as well as bulk-editing. There are three different view styles: list, small cards and large cards. A list of documents currently opened for editing is shown in the sidebar. @@ -368,7 +368,7 @@ src/app/app.component.ts 146 - The documents list shows all of your documents and allows for filtering as well as bulk-editing. There are three different view styles: list, small cards and large cards. A list of documents currently opened for editing is shown in the sidebar. + Lista de documente afișează toate documentele și permite atât filtrarea, cât și editarea în grup. Există trei stiluri de vizualizare diferite: listă, carduri mici și carduri mari. O listă de documente deschise în prezent pentru editare este afișată în bara laterală. The filtering tools allow you to quickly find documents using various searches, dates, tags, etc. @@ -376,7 +376,7 @@ src/app/app.component.ts 153 - The filtering tools allow you to quickly find documents using various searches, dates, tags, etc. + Instrumentele de filtrare vă permit să găsiți rapid documente folosind diverse căutări, date, etichete, etc. Any combination of filters can be saved as a 'view' which can then be displayed on the dashboard and / or sidebar. @@ -384,7 +384,7 @@ src/app/app.component.ts 159 - Any combination of filters can be saved as a 'view' which can then be displayed on the dashboard and / or sidebar. + Orice combinație de filtre poate fi salvată ca o 'vizualizare' care poate fi afișată apoi pe tabloul de bord și/sau pe bara laterală. Tags, correspondents, document types and storage paths can all be managed using these pages. They can also be created from the document edit view. @@ -392,7 +392,7 @@ src/app/app.component.ts 164 - Tags, correspondents, document types and storage paths can all be managed using these pages. They can also be created from the document edit view. + Tag-uri, corespondenți, tipuri de documente și căi de stocare pot fi gestionate toate folosind aceste pagini. De asemenea, pot fi create din editarea documentului. Manage e-mail accounts and rules for automatically importing documents. @@ -400,7 +400,7 @@ src/app/app.component.ts 172 - Manage e-mail accounts and rules for automatically importing documents. + Gestionați conturile de e-mail și regulile pentru importul automat de documente. Consumption templates give you finer control over the document ingestion process. @@ -408,7 +408,7 @@ src/app/app.component.ts 180 - Consumption templates give you finer control over the document ingestion process. + Şabloanele de consum vă oferă un control mai bun asupra procesului de ingestie a documentului. File Tasks shows you documents that have been consumed, are waiting to be, or may have failed during the process. @@ -416,7 +416,7 @@ src/app/app.component.ts 188 - File Tasks shows you documents that have been consumed, are waiting to be, or may have failed during the process. + Sarcinile fișierului vă arată documentele care au fost consumate, care așteaptă să fie, sau este posibil să fi eșuat în timpul procesului. Check out the settings for various tweaks to the web app and toggle settings for saved views. @@ -424,7 +424,7 @@ src/app/app.component.ts 196 - Check out the settings for various tweaks to the web app and toggle settings for saved views. + Verificați setările pentru diferite modificări ale aplicației web și comutați setările pentru vizualizările salvate. Thank you! 🙏 @@ -432,7 +432,7 @@ src/app/app.component.ts 204 - Thank you! 🙏 + Mulțumesc! :plided_hands: There are <em>tons</em> more features and info we didn't cover here, but this should get you started. Check out the documentation or visit the project on GitHub to learn more or to report issues. @@ -448,7 +448,7 @@ src/app/app.component.ts 208 - Lastly, on behalf of every contributor to this community-supported project, thank you for using Paperless-ngx! + În cele din urmă, în numele fiecărui colaborator la acest proiect sprijinit de comunitate, vă mulţumim pentru că ați folosit Paperless-ngx! Logs @@ -476,7 +476,7 @@ src/app/components/admin/tasks/tasks.component.html 15 - Auto refresh + Actualizare automată Loading... @@ -580,7 +580,7 @@ src/app/components/admin/settings/settings.component.html 2 - Start tour + Începeți turul Open Django Admin @@ -588,7 +588,7 @@ src/app/components/admin/settings/settings.component.html 4 - Open Django Admin + Deschideți Administratorul Django General @@ -596,7 +596,7 @@ src/app/components/admin/settings/settings.component.html 15 - General + Setări generale Appearance @@ -700,7 +700,7 @@ src/app/components/admin/settings/settings.component.html 99 - Sidebar + Bară laterală Use 'slim' sidebar (icons only) @@ -708,7 +708,7 @@ src/app/components/admin/settings/settings.component.html 103 - Use 'slim' sidebar (icons only) + Utilizaţi bara laterală "subţire" (numai pictograme) Dark mode @@ -748,7 +748,7 @@ src/app/components/admin/settings/settings.component.html 121 - Theme Color + Culoarea temei Reset @@ -756,7 +756,7 @@ src/app/components/admin/settings/settings.component.html 130 - Reset + Inițializare Update checking @@ -764,7 +764,7 @@ src/app/components/admin/settings/settings.component.html 135 - Update checking + Verificare actualizare Update checking works by pinging the public GitHub API for the latest release to determine whether a new version is available. Actual updating of the app must still be performed manually. @@ -1946,7 +1946,7 @@ src/app/components/admin/users-groups/users-groups.component.html 89 - No groups defined + Nu există grupuri definite Password has been changed, you will be logged out momentarily. @@ -2163,7 +2163,7 @@ src/app/components/app-frame/app-frame.component.html 45 - My Profile + Profilul meu Logout @@ -2327,7 +2327,7 @@ src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html 61 - Document Types + Tipuri de documente Storage Paths @@ -2343,7 +2343,7 @@ src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html 67 - Storage Paths + Căi de stocare Custom Fields @@ -2363,7 +2363,7 @@ src/app/components/manage/custom-fields/custom-fields.component.html 1 - Custom Fields + Câmpuri personalizate Consumption templates @@ -2371,7 +2371,7 @@ src/app/components/app-frame/app-frame.component.html 188 - Consumption templates + Șabloane de consum Templates @@ -2379,7 +2379,7 @@ src/app/components/app-frame/app-frame.component.html 191 - Templates + Șabloane Mail @@ -2391,7 +2391,7 @@ src/app/components/app-frame/app-frame.component.html 198 - Mail + Mail Administration @@ -2399,7 +2399,7 @@ src/app/components/app-frame/app-frame.component.html 204 - Administration + Administrare File Tasks @@ -2423,7 +2423,7 @@ src/app/components/app-frame/app-frame.component.html 252 - is available. + este disponibilă. Click to view. @@ -2431,7 +2431,7 @@ src/app/components/app-frame/app-frame.component.html 252 - Click to view. + Click pentru a vizualiza. Paperless-ngx can automatically check for updates @@ -2439,7 +2439,7 @@ src/app/components/app-frame/app-frame.component.html 256 - Paperless-ngx can automatically check for updates + Sistemul poate verifica automat actualizările How does this work? @@ -2447,7 +2447,7 @@ src/app/components/app-frame/app-frame.component.html 263,265 - How does this work? + Cum funcţionează? Update available @@ -2455,7 +2455,7 @@ src/app/components/app-frame/app-frame.component.html 274 - Update available + Actualizare disponibilă Sidebar views updated @@ -2463,7 +2463,7 @@ src/app/components/app-frame/app-frame.component.ts 252 - Sidebar views updated + Vizualizări bară laterală actualizate Error updating sidebar views @@ -2471,7 +2471,7 @@ src/app/components/app-frame/app-frame.component.ts 255 - Error updating sidebar views + Eroare la actualizarea vizualizărilor barei laterale An error occurred while saving update checking settings. @@ -2547,7 +2547,7 @@ src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.html 25 - Create New Field + Creare câmp nou Add @@ -2559,7 +2559,7 @@ src/app/components/common/permissions-select/permissions-select.component.html 7 - Add + Adaugă Choose field @@ -2567,7 +2567,7 @@ src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.ts 52 - Choose field + Selectare câmp No unused fields found @@ -2599,7 +2599,7 @@ src/app/components/manage/custom-fields/custom-fields.component.ts 66 - Error saving field. + Eroare la salvarea câmpului. now @@ -2607,7 +2607,7 @@ src/app/components/common/date-dropdown/date-dropdown.component.html 20 - now + acum After @@ -2667,7 +2667,7 @@ src/app/components/manage/consumption-templates/consumption-templates.component.html 15 - Sort order + Ordinea de sortare Filters @@ -2675,7 +2675,7 @@ src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html 18 - Filters + Filtre Process documents that match all filters specified below. @@ -2691,7 +2691,7 @@ src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html 20 - Filter sources + Filtrare surse Filter filename @@ -2699,7 +2699,7 @@ src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html 21 - Filter filename + Filtru nume fișier Apply to documents that match this filename. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. @@ -2707,7 +2707,7 @@ src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html 21 - Apply to documents that match this filename. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. + Aplică la documentele care se potrivesc cu acest nume de fișier. Wildcards cum ar fi *.pdf sau *factura* sunt permise. Masca insensibilă. Filter path @@ -2715,7 +2715,7 @@ src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html 22 - Filter path + Filtrare cale Apply to documents that match this path. Wildcards specified as * are allowed. Case insensitive.</a> @@ -2731,7 +2731,7 @@ src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html 23 - Filter mail rule + Regulă filtrare e-mail Apply to documents consumed via this mail rule. @@ -2739,7 +2739,7 @@ src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html 23 - Apply to documents consumed via this mail rule. + Aplică la documentele consumate prin această regulă de e-mail. Assignments @@ -3199,7 +3199,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts 15 - SSL + SSL STARTTLS @@ -3207,7 +3207,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts 16 - STARTTLS + STARTTLS Create new mail account @@ -3215,7 +3215,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts 41 - Create new mail account + Creează un cont de mail nou Edit mail account @@ -3223,7 +3223,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts 45 - Edit mail account + Editare cont de mail Successfully connected to the mail server @@ -3231,7 +3231,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts 90 - Successfully connected to the mail server + Conectat cu succes la serverul de e-mail Unable to connect to the mail server @@ -3239,7 +3239,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts 91 - Unable to connect to the mail server + Problemă la conectarea la server Account @@ -3251,7 +3251,7 @@ src/app/components/manage/mail/mail.component.html 67 - Account + Cont Folder @@ -3259,7 +3259,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 12 - Folder + Dosar Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server. @@ -3267,7 +3267,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 12 - Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server. + Subdosarele trebuie separate printr-un delimitator, adesea un punct ('.') sau slash ('/'), dar variază de la serverul de mail. Maximum age (days) @@ -3275,7 +3275,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 13 - Maximum age (days) + Vârsta maximă (zile) Attachment type @@ -3283,7 +3283,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 14 - Attachment type + Tip atașament Consumption scope @@ -3291,7 +3291,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 15 - Consumption scope + Sfera de consum See docs for .eml processing requirements @@ -3323,7 +3323,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 20 - Filter from + Filtrează de la Filter to @@ -3331,7 +3331,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 21 - Filter to + Filtrează către Filter subject @@ -3339,7 +3339,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 22 - Filter subject + Filtrează subiect Filter body @@ -3347,7 +3347,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 23 - Filter body + Filtrează corpul email-ului Filter attachment filename includes @@ -3355,7 +3355,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 24 - Filter attachment filename includes + Filtrul de nume al fișierului include Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. @@ -3371,7 +3371,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 25 - Filter attachment filename excluding + Filtru nume fișier atașat exclusiv Do not consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. @@ -3387,7 +3387,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 28 - Action + Acţiune Action is only performed when documents are consumed from the mail. Mails without attachments remain entirely untouched. @@ -3395,7 +3395,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 28 - Action is only performed when documents are consumed from the mail. Mails without attachments remain entirely untouched. + Acțiunea este efectuată numai atunci când documentele sunt consumate din e-mail. Mailurile fără atașamente rămân în întregime neatinse. Action parameter @@ -3403,7 +3403,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 29 - Action parameter + Parametru acțiune Assignments specified here will supersede any consumption templates. @@ -3411,7 +3411,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 30 - Assignments specified here will supersede any consumption templates. + Atribuirile specificate aici vor înlocui orice șabloane de consum. Assign title from @@ -3419,7 +3419,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 31 - Assign title from + Atribuie titlu din Assign correspondent from @@ -3427,7 +3427,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 34 - Assign correspondent from + Atribuie corespondent din Assign owner from rule @@ -3435,7 +3435,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 36 - Assign owner from rule + Atribuiți proprietarul din regulă Only process attachments @@ -3567,7 +3567,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts 145 - Create new mail rule + Creați o nouă regulă pentru mail Edit mail rule @@ -3575,7 +3575,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts 149 - Edit mail rule + Editați regula pentru e-mail Path @@ -3587,7 +3587,7 @@ src/app/components/manage/storage-path-list/storage-path-list.component.ts 42 - Path + Cale e.g. @@ -3595,7 +3595,7 @@ src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts 28 - e.g. + de ex. or use slashes to add directories e.g. @@ -3603,7 +3603,7 @@ src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts 30 - or use slashes to add directories e.g. + sau utilizaţi slash-uri pentru a adăuga directoare, de ex. See <a target="_blank" href="https://docs.paperless-ngx.com/advanced_usage/#file-name-handling">documentation</a> for full list. @@ -3619,7 +3619,7 @@ src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts 37 - Create new storage path + Creează o nouă cale de stocare Edit storage path @@ -3627,7 +3627,7 @@ src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts 41 - Edit storage path + Editează calea de stocare Color @@ -3683,7 +3683,7 @@ src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html 8 - Email + Poștă electronică First name @@ -3695,7 +3695,7 @@ src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html 28 - First name + Prenume Last name @@ -3707,7 +3707,7 @@ src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html 29 - Last name + Nume de familie Active @@ -3715,7 +3715,7 @@ src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html 19 - Active + Activ Superuser @@ -3723,7 +3723,7 @@ src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html 23 - Superuser + Super utilizator (Grants all permissions and can view objects) @@ -3731,7 +3731,7 @@ src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html 23 - (Grants all permissions and can view objects) + (Alocă toate permisiunile si pot vizualiza obiectele) Create new user account @@ -3739,7 +3739,7 @@ src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts 44 - Create new user account + Crează un nou cont de utilizator Edit user account @@ -3747,7 +3747,7 @@ src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts 48 - Edit user account + Editează contul de utilizator All @@ -4261,7 +4261,7 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.html 46 - Expires + Expiră Create @@ -4281,7 +4281,7 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts 97 - 1 day + 1 zi 7 days @@ -4289,7 +4289,7 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts 20 - 7 days + 7 zile 30 days @@ -4297,7 +4297,7 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts 21 - 30 days + 30 zile Never @@ -4305,7 +4305,7 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts 22 - Never + Niciodată Error retrieving links @@ -4313,7 +4313,7 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts 78 - Error retrieving links + Eroare la preluarea link-urilor days @@ -4321,7 +4321,7 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts 97 - days + Zile Error deleting link @@ -4329,7 +4329,7 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts 126 - Error deleting link + Eroare la ștergerea link-ului Error creating link @@ -4337,7 +4337,7 @@ src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts 156 - Error creating link + Eroare la crearea linkului Status @@ -4345,7 +4345,7 @@ src/app/components/common/toasts/toasts.component.html 22 - Status + Stare Copy Raw Error @@ -4353,7 +4353,7 @@ src/app/components/common/toasts/toasts.component.html 33 - Copy Raw Error + Eroare de copiere brută Hello , welcome to Paperless-ngx @@ -4377,7 +4377,7 @@ src/app/components/dashboard/dashboard.component.ts 71 - Dashboard updated + Tablou de bord actualizat Error updating dashboard @@ -4385,7 +4385,7 @@ src/app/components/dashboard/dashboard.component.ts 74 - Error updating dashboard + Eroare la actualizarea tabloului de bord Show all @@ -4457,7 +4457,7 @@ src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html 31 - View Preview + Vezi previzualizarea Download @@ -4489,7 +4489,7 @@ src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html 53 - No documents + Nu aveți documente Statistics @@ -4505,7 +4505,7 @@ src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html 4 - Go to inbox + Salt la primite Documents in inbox @@ -4513,7 +4513,7 @@ src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html 5 - Documents in inbox + Documente în mesaje primite Go to documents @@ -4521,7 +4521,7 @@ src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html 8 - Go to documents + Mergeți la documente Total documents diff --git a/src-ui/src/styles.scss b/src-ui/src/styles.scss index 19898374b..e128b27fa 100644 --- a/src-ui/src/styles.scss +++ b/src-ui/src/styles.scss @@ -555,6 +555,11 @@ table.table { } } +.popover-hidden .popover { + opacity: 0; + pointer-events: none; +} + // Tour .tour-active .popover { min-width: 360px; diff --git a/src/documents/barcodes.py b/src/documents/barcodes.py index cac02e3e9..3e2b309b6 100644 --- a/src/documents/barcodes.py +++ b/src/documents/barcodes.py @@ -14,6 +14,8 @@ from pikepdf import Pdf from PIL import Image from documents.converters import convert_from_tiff_to_pdf +from documents.data_models import ConsumableDocument +from documents.data_models import DocumentMetadataOverrides from documents.data_models import DocumentSource from documents.utils import copy_basic_file_stats from documents.utils import copy_file_with_basic_stats @@ -53,6 +55,7 @@ class BarcodeReader: self.mime: Final[str] = mime_type self.pdf_file: Path = self.file self.barcodes: list[Barcode] = [] + self._tiff_conversion_done = False self.temp_dir: Optional[tempfile.TemporaryDirectory] = None if settings.CONSUMER_BARCODE_TIFF_SUPPORT: @@ -150,12 +153,14 @@ class BarcodeReader: def convert_from_tiff_to_pdf(self): """ - May convert a TIFF image into a PDF, if the input is a TIFF + May convert a TIFF image into a PDF, if the input is a TIFF and + the TIFF has not been made into a PDF """ # Nothing to do, pdf_file is already assigned correctly - if self.mime != "image/tiff": + if self.mime != "image/tiff" or self._tiff_conversion_done: return + self._tiff_conversion_done = True self.pdf_file = convert_from_tiff_to_pdf(self.file, Path(self.temp_dir.name)) def detect(self) -> None: @@ -167,6 +172,9 @@ class BarcodeReader: if self.barcodes: return + # No op if not a TIFF + self.convert_from_tiff_to_pdf() + # Choose the library for reading if settings.CONSUMER_BARCODE_SCANNER == "PYZBAR": reader = self.read_barcodes_pyzbar @@ -240,7 +248,7 @@ class BarcodeReader: """ document_paths = [] - fname = self.file.with_suffix("").name + fname = self.file.stem with Pdf.open(self.pdf_file) as input_pdf: # Start with an empty document current_document: list[Page] = [] @@ -290,7 +298,7 @@ class BarcodeReader: def separate( self, source: DocumentSource, - override_name: Optional[str] = None, + overrides: DocumentMetadataOverrides, ) -> bool: """ Separates the document, based on barcodes and configuration, creating new @@ -316,27 +324,23 @@ class BarcodeReader: logger.warning("No pages to split on!") return False - # Create the split documents - doc_paths = self.separate_pages(separator_pages) + tmp_dir = Path(tempfile.mkdtemp(prefix="paperless-barcode-split-")).resolve() - # Save the new documents to correct folder - if source != DocumentSource.ConsumeFolder: - # The given file is somewhere in SCRATCH_DIR, - # and new documents must be moved to the CONSUMPTION_DIR - # for the consumer to notice them - save_to_dir = settings.CONSUMPTION_DIR - else: - # The given file is somewhere in CONSUMPTION_DIR, - # and may be some levels down for recursive tagging - # so use the file's parent to preserve any metadata - save_to_dir = self.file.parent + from documents import tasks - for idx, document_path in enumerate(doc_paths): - if override_name is not None: - newname = f"{idx}_{override_name}" - dest = save_to_dir / newname - else: - dest = save_to_dir - logger.info(f"Saving {document_path} to {dest}") - copy_file_with_basic_stats(document_path, dest) + # Create the split document tasks + for new_document in self.separate_pages(separator_pages): + copy_file_with_basic_stats(new_document, tmp_dir / new_document.name) + + tasks.consume_file.delay( + ConsumableDocument( + # Same source, for templates + source=source, + # Can't use same folder or the consume might grab it again + original_file=(tmp_dir / new_document.name).resolve(), + ), + # All the same metadata + overrides, + ) + logger.info("Barcode splitting complete!") return True diff --git a/src/documents/consumer.py b/src/documents/consumer.py index 4f97881ef..6a0d1ec02 100644 --- a/src/documents/consumer.py +++ b/src/documents/consumer.py @@ -691,6 +691,8 @@ class Consumer(LoggingMixin): added_month_name_short=local_added.strftime("%b"), added_day=local_added.strftime("%d"), owner_username=owner_username, + original_filename=Path(self.filename).stem, + added_time=local_added.strftime("%H:%M"), ).strip() def _store( diff --git a/src/documents/management/commands/document_exporter.py b/src/documents/management/commands/document_exporter.py index 4f3cb937a..8913b1b6f 100644 --- a/src/documents/management/commands/document_exporter.py +++ b/src/documents/management/commands/document_exporter.py @@ -238,18 +238,6 @@ class Command(BaseCommand): serializers.serialize("json", StoragePath.objects.all()), ) - notes = json.loads( - serializers.serialize("json", Note.objects.all()), - ) - if not self.split_manifest: - manifest += notes - - documents = Document.objects.order_by("id") - document_map = {d.pk: d for d in documents} - document_manifest = json.loads(serializers.serialize("json", documents)) - if not self.split_manifest: - manifest += document_manifest - manifest += json.loads( serializers.serialize("json", MailAccount.objects.all()), ) @@ -303,10 +291,24 @@ class Command(BaseCommand): serializers.serialize("json", CustomField.objects.all()), ) + # These are treated specially and included in the per-document manifest + # if that setting is enabled. Otherwise, they are just exported to the bulk + # manifest + documents = Document.objects.order_by("id") + document_map: dict[int, Document] = {d.pk: d for d in documents} + document_manifest = json.loads(serializers.serialize("json", documents)) + + notes = json.loads( + serializers.serialize("json", Note.objects.all()), + ) + + custom_field_instances = json.loads( + serializers.serialize("json", CustomFieldInstance.objects.all()), + ) if not self.split_manifest: - manifest += json.loads( - serializers.serialize("json", CustomFieldInstance.objects.all()), - ) + manifest += document_manifest + manifest += notes + manifest += custom_field_instances # 3. Export files from each document for index, document_dict in tqdm.tqdm( @@ -412,6 +414,12 @@ class Command(BaseCommand): notes, ), ) + content += list( + filter( + lambda d: d["fields"]["document"] == document_dict["pk"], + custom_field_instances, + ), + ) manifest_name.write_text( json.dumps(content, indent=2, ensure_ascii=False), encoding="utf-8", diff --git a/src/documents/management/commands/document_fuzzy_match.py b/src/documents/management/commands/document_fuzzy_match.py index 597a9d2c1..9e01ff1b0 100644 --- a/src/documents/management/commands/document_fuzzy_match.py +++ b/src/documents/management/commands/document_fuzzy_match.py @@ -53,6 +53,12 @@ class Command(MultiProcessMixin, ProgressBarMixin, BaseCommand): type=float, help="Ratio to consider documents a match", ) + parser.add_argument( + "--delete", + default=False, + action="store_true", + help="If set, one document of matches above the ratio WILL BE DELETED", + ) self.add_argument_progress_bar_mixin(parser) self.add_argument_processes_mixin(parser) @@ -63,6 +69,13 @@ class Command(MultiProcessMixin, ProgressBarMixin, BaseCommand): self.handle_processes_mixin(**options) self.handle_progress_bar_mixin(**options) + if options["delete"]: + self.stdout.write( + self.style.WARNING( + "The command is configured to delete documents. Use with caution", + ), + ) + opt_ratio = options["ratio"] checked_pairs: set[tuple[int, int]] = set() work_pkgs: list[_WorkPackage] = [] @@ -81,15 +94,12 @@ class Command(MultiProcessMixin, ProgressBarMixin, BaseCommand): continue # Skip matching which have already been matched together # doc 1 to doc 2 is the same as doc 2 to doc 1 - if (first_doc.pk, second_doc.pk) in checked_pairs or ( - second_doc.pk, - first_doc.pk, - ) in checked_pairs: + doc_1_to_doc_2 = (first_doc.pk, second_doc.pk) + doc_2_to_doc_1 = doc_1_to_doc_2[::-1] + if doc_1_to_doc_2 in checked_pairs or doc_2_to_doc_1 in checked_pairs: continue - checked_pairs.update( - [(first_doc.pk, second_doc.pk), (second_doc.pk, first_doc.pk)], - ) - + checked_pairs.update([doc_1_to_doc_2, doc_2_to_doc_1]) + # Actually something useful to work on now work_pkgs.append(_WorkPackage(first_doc, second_doc)) # Don't spin up a pool of 1 process @@ -109,6 +119,7 @@ class Command(MultiProcessMixin, ProgressBarMixin, BaseCommand): # Check results messages = [] + maybe_delete_ids = [] for result in sorted(results): if result.ratio >= opt_ratio: messages.append( @@ -117,6 +128,7 @@ class Command(MultiProcessMixin, ProgressBarMixin, BaseCommand): f" to {result.doc_two_pk} (confidence {result.ratio:.3f})", ), ) + maybe_delete_ids.append(result.doc_two_pk) if len(messages) == 0: messages.append( @@ -125,3 +137,10 @@ class Command(MultiProcessMixin, ProgressBarMixin, BaseCommand): self.stdout.writelines( messages, ) + if options["delete"]: + self.stdout.write( + self.style.NOTICE( + f"Deleting {len(maybe_delete_ids)} documents based on ratio matches", + ), + ) + Document.objects.filter(pk__in=maybe_delete_ids).delete() diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 10a44a8fe..d0728a719 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -140,7 +140,7 @@ def consume_file( with BarcodeReader(input_doc.original_file, input_doc.mime_type) as reader: if settings.CONSUMER_ENABLE_BARCODES and reader.separate( input_doc.source, - overrides.filename, + overrides, ): # notify the sender, otherwise the progress bar # in the UI stays stuck diff --git a/src/documents/tests/test_barcodes.py b/src/documents/tests/test_barcodes.py index 70f7807cc..e4d8ccc57 100644 --- a/src/documents/tests/test_barcodes.py +++ b/src/documents/tests/test_barcodes.py @@ -1,5 +1,4 @@ import shutil -from pathlib import Path from unittest import mock import pytest @@ -11,10 +10,13 @@ from documents import tasks from documents.barcodes import BarcodeReader from documents.consumer import ConsumerError from documents.data_models import ConsumableDocument +from documents.data_models import DocumentMetadataOverrides from documents.data_models import DocumentSource from documents.models import Document from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import DocumentConsumeDelayMixin from documents.tests.utils import FileSystemAssertsMixin +from documents.tests.utils import SampleDirMixin try: import zxingcpp # noqa: F401 @@ -25,11 +27,7 @@ except ImportError: @override_settings(CONSUMER_BARCODE_SCANNER="PYZBAR") -class TestBarcode(DirectoriesMixin, FileSystemAssertsMixin, TestCase): - SAMPLE_DIR = Path(__file__).parent / "samples" - - BARCODE_SAMPLE_DIR = SAMPLE_DIR / "barcodes" - +class TestBarcode(DirectoriesMixin, FileSystemAssertsMixin, SampleDirMixin, TestCase): def test_scan_file_for_separating_barcodes(self): """ GIVEN: @@ -48,6 +46,46 @@ class TestBarcode(DirectoriesMixin, FileSystemAssertsMixin, TestCase): self.assertEqual(reader.pdf_file, test_file) self.assertDictEqual(separator_page_numbers, {0: False}) + @override_settings( + CONSUMER_BARCODE_TIFF_SUPPORT=True, + ) + def test_scan_tiff_for_separating_barcodes(self): + """ + GIVEN: + - TIFF image containing barcodes + WHEN: + - Consume task returns + THEN: + - The file was split + """ + test_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle.tiff" + + with BarcodeReader(test_file, "image/tiff") as reader: + reader.detect() + separator_page_numbers = reader.get_separation_pages() + + self.assertDictEqual(separator_page_numbers, {1: False}) + + @override_settings( + CONSUMER_BARCODE_TIFF_SUPPORT=True, + ) + def test_scan_tiff_with_alpha_for_separating_barcodes(self): + """ + GIVEN: + - TIFF image containing barcodes + WHEN: + - Consume task returns + THEN: + - The file was split + """ + test_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle-alpha.tiff" + + with BarcodeReader(test_file, "image/tiff") as reader: + reader.detect() + separator_page_numbers = reader.get_separation_pages() + + self.assertDictEqual(separator_page_numbers, {1: False}) + def test_scan_file_for_separating_barcodes_none_present(self): """ GIVEN: @@ -285,6 +323,28 @@ class TestBarcode(DirectoriesMixin, FileSystemAssertsMixin, TestCase): self.assertGreater(len(reader.barcodes), 0) self.assertDictEqual(separator_page_numbers, {1: False}) + def test_scan_file_for_separating_barcodes_password(self): + """ + GIVEN: + - Password protected PDF + WHEN: + - File is scanned for barcode + THEN: + - Scanning handles the exception without crashing + """ + test_file = self.SAMPLE_DIR / "password-is-test.pdf" + with self.assertLogs("paperless.barcodes", level="WARNING") as cm: + with BarcodeReader(test_file, "application/pdf") as reader: + reader.detect() + warning = cm.output[0] + expected_str = "WARNING:paperless.barcodes:File is likely password protected, not checking for barcodes" + self.assertTrue(warning.startswith(expected_str)) + + separator_page_numbers = reader.get_separation_pages() + + self.assertEqual(reader.pdf_file, test_file) + self.assertDictEqual(separator_page_numbers, {}) + def test_separate_pages(self): """ GIVEN: @@ -332,8 +392,12 @@ class TestBarcode(DirectoriesMixin, FileSystemAssertsMixin, TestCase): with self.assertLogs("paperless.barcodes", level="WARNING") as cm: with BarcodeReader(test_file, "application/pdf") as reader: - success = reader.separate(DocumentSource.ApiUpload) - self.assertFalse(success) + self.assertFalse( + reader.separate( + DocumentSource.ApiUpload, + DocumentMetadataOverrides(), + ), + ) self.assertEqual( cm.output, [ @@ -341,215 +405,6 @@ class TestBarcode(DirectoriesMixin, FileSystemAssertsMixin, TestCase): ], ) - def test_save_to_dir_given_name(self): - """ - GIVEN: - - File to save to a directory - - There is a name override - WHEN: - - The file is saved - THEN: - - The file exists - """ - test_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle.pdf" - with BarcodeReader(test_file, "application/pdf") as reader: - reader.separate(DocumentSource.ApiUpload, "newname.pdf") - - self.assertEqual(reader.pdf_file, test_file) - target_file1 = settings.CONSUMPTION_DIR / "0_newname.pdf" - target_file2 = settings.CONSUMPTION_DIR / "1_newname.pdf" - self.assertIsFile(target_file1) - self.assertIsFile(target_file2) - - def test_barcode_splitter_api_upload(self): - """ - GIVEN: - - Input file containing barcodes - WHEN: - - Input file is split on barcodes - THEN: - - Correct number of files produced - """ - sample_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle.pdf" - test_file = settings.SCRATCH_DIR / "patch-code-t-middle.pdf" - shutil.copy(sample_file, test_file) - - with BarcodeReader(test_file, "application/pdf") as reader: - reader.separate(DocumentSource.ApiUpload) - - self.assertEqual(reader.pdf_file, test_file) - - target_file1 = ( - settings.CONSUMPTION_DIR / "patch-code-t-middle_document_0.pdf" - ) - - target_file2 = ( - settings.CONSUMPTION_DIR / "patch-code-t-middle_document_1.pdf" - ) - - self.assertIsFile(target_file1) - self.assertIsFile(target_file2) - - def test_barcode_splitter_consume_dir(self): - """ - GIVEN: - - Input file containing barcodes - WHEN: - - Input file is split on barcodes - THEN: - - Correct number of files produced - """ - sample_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle.pdf" - test_file = settings.CONSUMPTION_DIR / "patch-code-t-middle.pdf" - shutil.copy(sample_file, test_file) - - with BarcodeReader(test_file, "application/pdf") as reader: - reader.detect() - reader.separate(DocumentSource.ConsumeFolder) - - self.assertEqual(reader.pdf_file, test_file) - - target_file1 = ( - settings.CONSUMPTION_DIR / "patch-code-t-middle_document_0.pdf" - ) - - target_file2 = ( - settings.CONSUMPTION_DIR / "patch-code-t-middle_document_1.pdf" - ) - - self.assertIsFile(target_file1) - self.assertIsFile(target_file2) - - def test_barcode_splitter_consume_dir_recursive(self): - """ - GIVEN: - - Input file containing barcodes - - Input file is within a directory structure of the consume folder - WHEN: - - Input file is split on barcodes - THEN: - - Correct number of files produced - - Output files are within the same directory structure - """ - sample_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle.pdf" - test_file = ( - settings.CONSUMPTION_DIR / "tag1" / "tag2" / "patch-code-t-middle.pdf" - ) - test_file.parent.mkdir(parents=True) - shutil.copy(sample_file, test_file) - - with BarcodeReader(test_file, "application/pdf") as reader: - reader.separate(DocumentSource.ConsumeFolder) - - self.assertEqual(reader.pdf_file, test_file) - - target_file1 = ( - settings.CONSUMPTION_DIR - / "tag1" - / "tag2" - / "patch-code-t-middle_document_0.pdf" - ) - - target_file2 = ( - settings.CONSUMPTION_DIR - / "tag1" - / "tag2" - / "patch-code-t-middle_document_1.pdf" - ) - - self.assertIsFile(target_file1) - self.assertIsFile(target_file2) - - @override_settings(CONSUMER_ENABLE_BARCODES=True) - def test_consume_barcode_file(self): - """ - GIVEN: - - Input file with barcodes given to consume task - WHEN: - - Consume task returns - THEN: - - The file was split - """ - test_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle.pdf" - - dst = settings.SCRATCH_DIR / "patch-code-t-middle.pdf" - shutil.copy(test_file, dst) - - with mock.patch("documents.tasks.async_to_sync"): - self.assertEqual( - tasks.consume_file( - ConsumableDocument( - source=DocumentSource.ConsumeFolder, - original_file=dst, - ), - None, - ), - "File successfully split", - ) - - @override_settings( - CONSUMER_ENABLE_BARCODES=True, - CONSUMER_BARCODE_TIFF_SUPPORT=True, - ) - def test_consume_barcode_tiff_file(self): - """ - GIVEN: - - TIFF image containing barcodes - WHEN: - - Consume task returns - THEN: - - The file was split - """ - test_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle.tiff" - - dst = settings.SCRATCH_DIR / "patch-code-t-middle.tiff" - shutil.copy(test_file, dst) - - with mock.patch("documents.tasks.async_to_sync"): - self.assertEqual( - tasks.consume_file( - ConsumableDocument( - source=DocumentSource.ConsumeFolder, - original_file=dst, - ), - None, - ), - "File successfully split", - ) - self.assertIsNotFile(dst) - - @override_settings( - CONSUMER_ENABLE_BARCODES=True, - CONSUMER_BARCODE_TIFF_SUPPORT=True, - ) - def test_consume_barcode_tiff_file_with_alpha(self): - """ - GIVEN: - - TIFF image containing barcodes - - TIFF image has an alpha layer - WHEN: - - Consume task handles the alpha layer and returns - THEN: - - The file was split without issue - """ - test_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle-alpha.tiff" - - dst = settings.SCRATCH_DIR / "patch-code-t-middle.tiff" - shutil.copy(test_file, dst) - - with mock.patch("documents.tasks.async_to_sync"): - self.assertEqual( - tasks.consume_file( - ConsumableDocument( - source=DocumentSource.ConsumeFolder, - original_file=dst, - ), - None, - ), - "File successfully split", - ) - self.assertIsNotFile(dst) - @override_settings( CONSUMER_ENABLE_BARCODES=True, CONSUMER_BARCODE_TIFF_SUPPORT=True, @@ -597,60 +452,6 @@ class TestBarcode(DirectoriesMixin, FileSystemAssertsMixin, TestCase): self.assertIsNone(kwargs["override_document_type_id"]) self.assertIsNone(kwargs["override_tag_ids"]) - @override_settings( - CONSUMER_ENABLE_BARCODES=True, - CONSUMER_BARCODE_TIFF_SUPPORT=True, - ) - def test_consume_barcode_supported_no_extension_file(self): - """ - GIVEN: - - TIFF image containing barcodes - - TIFF file is given without extension - WHEN: - - Consume task returns - THEN: - - The file was split - """ - test_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle.tiff" - - dst = settings.SCRATCH_DIR / "patch-code-t-middle" - shutil.copy(test_file, dst) - - with mock.patch("documents.tasks.async_to_sync"): - self.assertEqual( - tasks.consume_file( - ConsumableDocument( - source=DocumentSource.ConsumeFolder, - original_file=dst, - ), - None, - ), - "File successfully split", - ) - self.assertIsNotFile(dst) - - def test_scan_file_for_separating_barcodes_password(self): - """ - GIVEN: - - Password protected PDF - WHEN: - - File is scanned for barcode - THEN: - - Scanning handles the exception without crashing - """ - test_file = self.SAMPLE_DIR / "password-is-test.pdf" - with self.assertLogs("paperless.barcodes", level="WARNING") as cm: - with BarcodeReader(test_file, "application/pdf") as reader: - reader.detect() - warning = cm.output[0] - expected_str = "WARNING:paperless.barcodes:File is likely password protected, not checking for barcodes" - self.assertTrue(warning.startswith(expected_str)) - - separator_page_numbers = reader.get_separation_pages() - - self.assertEqual(reader.pdf_file, test_file) - self.assertDictEqual(separator_page_numbers, {}) - @override_settings( CONSUMER_ENABLE_BARCODES=True, CONSUMER_ENABLE_ASN_BARCODE=True, @@ -722,11 +523,64 @@ class TestBarcode(DirectoriesMixin, FileSystemAssertsMixin, TestCase): self.assertEqual(len(document_list), 5) -class TestAsnBarcode(DirectoriesMixin, TestCase): - SAMPLE_DIR = Path(__file__).parent / "samples" +@override_settings(CONSUMER_BARCODE_SCANNER="PYZBAR") +class TestBarcodeNewConsume( + DirectoriesMixin, + FileSystemAssertsMixin, + SampleDirMixin, + DocumentConsumeDelayMixin, + TestCase, +): + @override_settings(CONSUMER_ENABLE_BARCODES=True) + def test_consume_barcode_file(self): + """ + GIVEN: + - Incoming file with at 1 barcode producing 2 documents + - Document includes metadata override information + WHEN: + - The document is split + THEN: + - Two new consume tasks are created + - Metadata overrides are preserved for the new consume + - The document source is unchanged (for consume templates) + """ + test_file = self.BARCODE_SAMPLE_DIR / "patch-code-t-middle.pdf" + temp_copy = self.dirs.scratch_dir / test_file.name + shutil.copy(test_file, temp_copy) - BARCODE_SAMPLE_DIR = SAMPLE_DIR / "barcodes" + overrides = DocumentMetadataOverrides(tag_ids=[1, 2, 9]) + with mock.patch("documents.tasks.async_to_sync") as progress_mocker: + self.assertEqual( + tasks.consume_file( + ConsumableDocument( + source=DocumentSource.ConsumeFolder, + original_file=temp_copy, + ), + overrides, + ), + "File successfully split", + ) + # We let the consumer know progress is done + progress_mocker.assert_called_once() + # 2 new document consume tasks created + self.assertEqual(self.consume_file_mock.call_count, 2) + + self.assertIsNotFile(temp_copy) + + # Check the split files exist + # Check the source is unchanged + # Check the overrides are unchanged + for ( + new_input_doc, + new_doc_overrides, + ) in self.get_all_consume_delay_call_args(): + self.assertEqual(new_input_doc.source, DocumentSource.ConsumeFolder) + self.assertIsFile(new_input_doc.original_file) + self.assertEqual(overrides, new_doc_overrides) + + +class TestAsnBarcode(DirectoriesMixin, SampleDirMixin, TestCase): @override_settings(CONSUMER_ASN_BARCODE_PREFIX="CUSTOM-PREFIX-") def test_scan_file_for_asn_custom_prefix(self): """ diff --git a/src/documents/tests/test_management_exporter.py b/src/documents/tests/test_management_exporter.py index b4dc5720a..54bb6f34c 100644 --- a/src/documents/tests/test_management_exporter.py +++ b/src/documents/tests/test_management_exporter.py @@ -646,10 +646,13 @@ class TestExportImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase): with paperless_environment(): self.assertEqual(Document.objects.count(), 4) + self.assertEqual(CustomFieldInstance.objects.count(), 1) Document.objects.all().delete() + CustomFieldInstance.objects.all().delete() self.assertEqual(Document.objects.count(), 0) call_command("document_importer", "--no-progress-bar", self.target) self.assertEqual(Document.objects.count(), 4) + self.assertEqual(CustomFieldInstance.objects.count(), 1) def test_folder_prefix(self): """ diff --git a/src/documents/tests/test_management_fuzzy.py b/src/documents/tests/test_management_fuzzy.py index abbf3c921..c215c43ca 100644 --- a/src/documents/tests/test_management_fuzzy.py +++ b/src/documents/tests/test_management_fuzzy.py @@ -157,3 +157,55 @@ class TestFuzzyMatchCommand(TestCase): self.assertRegex(lines[0], self.MSG_REGEX) self.assertRegex(lines[1], self.MSG_REGEX) self.assertRegex(lines[2], self.MSG_REGEX) + + def test_document_deletion(self): + """ + GIVEN: + - 3 documents exist + - Document 1 to document 3 has a similarity over 85.0 + WHEN: + - Command is called with the --delete option + THEN: + - User is warned about the deletion flag + - Document 3 is deleted + - Documents 1 and 2 remain + """ + # Content similarity is 86.667 + Document.objects.create( + checksum="BEEFCAFE", + title="A", + content="first document scanned by bob", + mime_type="application/pdf", + filename="test.pdf", + ) + Document.objects.create( + checksum="DEADBEAF", + title="A", + content="second document scanned by alice", + mime_type="application/pdf", + filename="other_test.pdf", + ) + Document.objects.create( + checksum="CATTLE", + title="A", + content="first document scanned by pete", + mime_type="application/pdf", + filename="final_test.pdf", + ) + + self.assertEqual(Document.objects.count(), 3) + + stdout, _ = self.call_command("--delete") + print(stdout) + lines = [x.strip() for x in stdout.split("\n") if len(x.strip())] + self.assertEqual(len(lines), 3) + self.assertEqual( + lines[0], + "The command is configured to delete documents. Use with caution", + ) + self.assertRegex(lines[1], self.MSG_REGEX) + self.assertEqual(lines[2], "Deleting 1 documents based on ratio matches") + + self.assertEqual(Document.objects.count(), 2) + self.assertIsNotNone(Document.objects.get(pk=1)) + self.assertIsNotNone(Document.objects.get(pk=2)) diff --git a/src/documents/tests/utils.py b/src/documents/tests/utils.py index b1e9c0523..fe7dbb059 100644 --- a/src/documents/tests/utils.py +++ b/src/documents/tests/utils.py @@ -235,8 +235,10 @@ class DocumentConsumeDelayMixin: """ Iterates over all calls to the async task and returns the arguments """ + # Must be at least 1 call + self.consume_file_mock.assert_called() - for args, _ in self.consume_file_mock.call_args_list: + for args, kwargs in self.consume_file_mock.call_args_list: input_doc, overrides = args yield (input_doc, overrides) @@ -244,7 +246,7 @@ class DocumentConsumeDelayMixin: def get_specific_consume_delay_call_args( self, index: int, - ) -> Iterator[tuple[ConsumableDocument, DocumentMetadataOverrides]]: + ) -> tuple[ConsumableDocument, DocumentMetadataOverrides]: """ Returns the arguments of a specific call to the async task """ @@ -299,3 +301,9 @@ class TestMigrations(TransactionTestCase): def setUpBeforeMigration(self, apps): pass + + +class SampleDirMixin: + SAMPLE_DIR = Path(__file__).parent / "samples" + + BARCODE_SAMPLE_DIR = SAMPLE_DIR / "barcodes" diff --git a/src/documents/views.py b/src/documents/views.py index 6533c22f3..e8c6db0de 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -182,10 +182,14 @@ class PassUserMixin(CreateModelMixin): class CorrespondentViewSet(ModelViewSet, PassUserMixin): model = Correspondent - queryset = Correspondent.objects.annotate( - document_count=Count("documents"), - last_correspondence=Max("documents__created"), - ).order_by(Lower("name")) + queryset = ( + Correspondent.objects.annotate( + document_count=Count("documents"), + last_correspondence=Max("documents__created"), + ) + .select_related("owner") + .order_by(Lower("name")) + ) serializer_class = CorrespondentSerializer pagination_class = StandardPagination @@ -208,8 +212,12 @@ class CorrespondentViewSet(ModelViewSet, PassUserMixin): class TagViewSet(ModelViewSet, PassUserMixin): model = Tag - queryset = Tag.objects.annotate(document_count=Count("documents")).order_by( - Lower("name"), + queryset = ( + Tag.objects.annotate(document_count=Count("documents")) + .select_related("owner") + .order_by( + Lower("name"), + ) ) def get_serializer_class(self, *args, **kwargs): @@ -232,9 +240,13 @@ class TagViewSet(ModelViewSet, PassUserMixin): class DocumentTypeViewSet(ModelViewSet, PassUserMixin): model = DocumentType - queryset = DocumentType.objects.annotate( - document_count=Count("documents"), - ).order_by(Lower("name")) + queryset = ( + DocumentType.objects.annotate( + document_count=Count("documents"), + ) + .select_related("owner") + .order_by(Lower("name")) + ) serializer_class = DocumentTypeSerializer pagination_class = StandardPagination @@ -283,7 +295,12 @@ class DocumentViewSet( ) def get_queryset(self): - return Document.objects.distinct().annotate(num_notes=Count("notes")) + return ( + Document.objects.distinct() + .annotate(num_notes=Count("notes")) + .select_related("correspondent", "storage_path", "document_type", "owner") + .prefetch_related("tags", "custom_fields", "notes") + ) def get_serializer(self, *args, **kwargs): fields_param = self.request.query_params.get("fields", None) @@ -627,9 +644,18 @@ class DocumentViewSet( class SearchResultSerializer(DocumentSerializer, PassUserMixin): def to_representation(self, instance): - doc = Document.objects.get(id=instance["id"]) + doc = ( + Document.objects.select_related( + "correspondent", + "storage_path", + "document_type", + "owner", + ) + .prefetch_related("tags", "custom_fields", "notes") + .get(id=instance["id"]) + ) notes = ",".join( - [str(c.note) for c in Note.objects.filter(document=instance["id"])], + [str(c.note) for c in doc.notes.all()], ) r = super().to_representation(doc) r["__search_hit__"] = { @@ -752,7 +778,11 @@ class SavedViewViewSet(ModelViewSet, PassUserMixin): def get_queryset(self): user = self.request.user - return SavedView.objects.filter(owner=user) + return ( + SavedView.objects.filter(owner=user) + .select_related("owner") + .prefetch_related("filter_rules") + ) def perform_create(self, serializer): serializer.save(owner=self.request.user) @@ -1080,8 +1110,12 @@ class BulkDownloadView(GenericAPIView): class StoragePathViewSet(ModelViewSet, PassUserMixin): model = StoragePath - queryset = StoragePath.objects.annotate(document_count=Count("documents")).order_by( - Lower("name"), + queryset = ( + StoragePath.objects.annotate(document_count=Count("documents")) + .select_related("owner") + .order_by( + Lower("name"), + ) ) serializer_class = StoragePathSerializer @@ -1347,7 +1381,18 @@ class ConsumptionTemplateViewSet(ModelViewSet): model = ConsumptionTemplate - queryset = ConsumptionTemplate.objects.all().order_by("order") + queryset = ( + ConsumptionTemplate.objects.prefetch_related( + "assign_tags", + "assign_view_users", + "assign_view_groups", + "assign_change_users", + "assign_change_groups", + "assign_custom_fields", + ) + .all() + .order_by("order") + ) class CustomFieldViewSet(ModelViewSet): diff --git a/src/locale/fr_FR/LC_MESSAGES/django.po b/src/locale/fr_FR/LC_MESSAGES/django.po index 2cbfe6617..b6b2f9ca0 100644 --- a/src/locale/fr_FR/LC_MESSAGES/django.po +++ b/src/locale/fr_FR/LC_MESSAGES/django.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-12-05 08:26-0800\n" -"PO-Revision-Date: 2023-12-12 00:24\n" +"PO-Revision-Date: 2023-12-14 00:23\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" diff --git a/src/locale/hr_HR/LC_MESSAGES/django.po b/src/locale/hr_HR/LC_MESSAGES/django.po index 8a6450d04..2238b348e 100644 --- a/src/locale/hr_HR/LC_MESSAGES/django.po +++ b/src/locale/hr_HR/LC_MESSAGES/django.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-12-05 08:26-0800\n" -"PO-Revision-Date: 2023-12-05 16:27\n" +"PO-Revision-Date: 2023-12-13 12:09\n" "Last-Translator: \n" "Language-Team: Croatian\n" "Language: hr_HR\n" diff --git a/src/locale/ro_RO/LC_MESSAGES/django.po b/src/locale/ro_RO/LC_MESSAGES/django.po index 68b54c0c1..dc1f52e32 100644 --- a/src/locale/ro_RO/LC_MESSAGES/django.po +++ b/src/locale/ro_RO/LC_MESSAGES/django.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-12-05 08:26-0800\n" -"PO-Revision-Date: 2023-12-05 16:27\n" +"PO-Revision-Date: 2023-12-16 00:23\n" "Last-Translator: \n" "Language-Team: Romanian\n" "Language: ro_RO\n" @@ -23,11 +23,11 @@ msgstr "Documente" #: documents/models.py:36 documents/models.py:734 msgid "owner" -msgstr "" +msgstr "proprietar" #: documents/models.py:53 msgid "None" -msgstr "" +msgstr "Nimic" #: documents/models.py:54 msgid "Any word" @@ -108,15 +108,15 @@ msgstr "tipuri de document" #: documents/models.py:124 msgid "path" -msgstr "" +msgstr "cale" #: documents/models.py:129 documents/models.py:156 msgid "storage path" -msgstr "" +msgstr "cale de stocare" #: documents/models.py:130 msgid "storage paths" -msgstr "" +msgstr "căi de stocare" #: documents/models.py:137 msgid "Unencrypted" @@ -193,11 +193,11 @@ msgstr "Numele curent al arhivei stocate" #: documents/models.py:250 msgid "original filename" -msgstr "" +msgstr "numele original al fișierului" #: documents/models.py:256 msgid "The original name of the file when it was uploaded" -msgstr "" +msgstr "Numele original al fișierului când a fost încărcat" #: documents/models.py:263 msgid "archive serial number" @@ -381,47 +381,47 @@ msgstr "" #: documents/models.py:447 msgid "storage path is" -msgstr "" +msgstr "calea de stocare este" #: documents/models.py:448 msgid "has correspondent in" -msgstr "" +msgstr "are corespondent în" #: documents/models.py:449 msgid "does not have correspondent in" -msgstr "" +msgstr "nu are corespondent în" #: documents/models.py:450 msgid "has document type in" -msgstr "" +msgstr "are tip de document în" #: documents/models.py:451 msgid "does not have document type in" -msgstr "" +msgstr "nu are tip document în" #: documents/models.py:452 msgid "has storage path in" -msgstr "" +msgstr "are cale de stocare în" #: documents/models.py:453 msgid "does not have storage path in" -msgstr "" +msgstr "nu are cale de stocare în" #: documents/models.py:454 msgid "owner is" -msgstr "" +msgstr "proprietarul este" #: documents/models.py:455 msgid "has owner in" -msgstr "" +msgstr "are proprietar în" #: documents/models.py:456 msgid "does not have owner" -msgstr "" +msgstr "nu are proprietar" #: documents/models.py:457 msgid "does not have owner in" -msgstr "" +msgstr "nu are proprietar în" #: documents/models.py:467 msgid "rule type" @@ -441,47 +441,47 @@ msgstr "reguli de filtrare" #: documents/models.py:584 msgid "Task ID" -msgstr "" +msgstr "ID Sarcină" #: documents/models.py:585 msgid "Celery ID for the Task that was run" -msgstr "" +msgstr "ID-ul sarcinii Celery care a fost rulată" #: documents/models.py:590 msgid "Acknowledged" -msgstr "" +msgstr "Confirmat" #: documents/models.py:591 msgid "If the task is acknowledged via the frontend or API" -msgstr "" +msgstr "Dacă sarcina este confirmată prin frontend sau API" #: documents/models.py:597 msgid "Task Filename" -msgstr "" +msgstr "Numele fișierului sarcină" #: documents/models.py:598 msgid "Name of the file which the Task was run for" -msgstr "" +msgstr "Numele fișierului pentru care sarcina a fost executată" #: documents/models.py:604 msgid "Task Name" -msgstr "" +msgstr "Nume sarcină" #: documents/models.py:605 msgid "Name of the Task which was run" -msgstr "" +msgstr "Numele sarcinii care a fost executată" #: documents/models.py:612 msgid "Task State" -msgstr "" +msgstr "Stare sarcină" #: documents/models.py:613 msgid "Current state of the task being run" -msgstr "" +msgstr "Stadiul actual al sarcinii în curs de desfășurare" #: documents/models.py:618 msgid "Created DateTime" -msgstr "" +msgstr "Data creării" #: documents/models.py:619 msgid "Datetime field when the task result was created in UTC" @@ -489,7 +489,7 @@ msgstr "" #: documents/models.py:624 msgid "Started DateTime" -msgstr "" +msgstr "Data începerii" #: documents/models.py:625 msgid "Datetime field when the task was started in UTC" @@ -497,7 +497,7 @@ msgstr "" #: documents/models.py:630 msgid "Completed DateTime" -msgstr "" +msgstr "Data finalizării" #: documents/models.py:631 msgid "Datetime field when the task was completed in UTC" @@ -505,15 +505,15 @@ msgstr "" #: documents/models.py:636 msgid "Result Data" -msgstr "" +msgstr "Datele rezultatului" #: documents/models.py:638 msgid "The data returned by the task" -msgstr "" +msgstr "Datele returnate de sarcină" #: documents/models.py:650 msgid "Note for the document" -msgstr "" +msgstr "Notă pentru document" #: documents/models.py:674 msgid "user" @@ -521,23 +521,23 @@ msgstr "utilizator" #: documents/models.py:679 msgid "note" -msgstr "" +msgstr "notă" #: documents/models.py:680 msgid "notes" -msgstr "" +msgstr "note" #: documents/models.py:688 msgid "Archive" -msgstr "" +msgstr "Arhivă" #: documents/models.py:689 msgid "Original" -msgstr "" +msgstr "Original" #: documents/models.py:700 msgid "expiration" -msgstr "" +msgstr "expirare" #: documents/models.py:707 msgid "slug" @@ -545,35 +545,35 @@ msgstr "" #: documents/models.py:739 msgid "share link" -msgstr "" +msgstr "link de partajare" #: documents/models.py:740 msgid "share links" -msgstr "" +msgstr "link-uri de partajare" #: documents/models.py:752 msgid "String" -msgstr "" +msgstr "Şir de caractere" #: documents/models.py:753 msgid "URL" -msgstr "" +msgstr "Adresă URL" #: documents/models.py:754 msgid "Date" -msgstr "" +msgstr "Dată" #: documents/models.py:755 msgid "Boolean" -msgstr "" +msgstr "Boolean" #: documents/models.py:756 msgid "Integer" -msgstr "" +msgstr "Număr întreg" #: documents/models.py:757 msgid "Float" -msgstr "" +msgstr "Număr zecimal" #: documents/models.py:758 msgid "Monetary" @@ -581,11 +581,11 @@ msgstr "" #: documents/models.py:759 msgid "Document Link" -msgstr "" +msgstr "Link document" #: documents/models.py:771 msgid "data type" -msgstr "" +msgstr "tip date" #: documents/models.py:779 msgid "custom field" diff --git a/src/locale/zh_TW/LC_MESSAGES/django.po b/src/locale/zh_TW/LC_MESSAGES/django.po index e11c8ed0d..ab28d2394 100644 --- a/src/locale/zh_TW/LC_MESSAGES/django.po +++ b/src/locale/zh_TW/LC_MESSAGES/django.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-12-05 08:26-0800\n" -"PO-Revision-Date: 2023-12-05 16:27\n" +"PO-Revision-Date: 2023-12-14 00:23\n" "Last-Translator: \n" "Language-Team: Chinese Traditional\n" "Language: zh_TW\n" @@ -47,7 +47,7 @@ msgstr "" #: documents/models.py:58 msgid "Fuzzy word" -msgstr "" +msgstr "模糊詞" #: documents/models.py:59 msgid "Automatic" @@ -68,15 +68,15 @@ msgstr "比對演算法" #: documents/models.py:72 msgid "is insensitive" -msgstr "" +msgstr "不區分大小寫" #: documents/models.py:95 documents/models.py:147 msgid "correspondent" -msgstr "" +msgstr "聯繫者" #: documents/models.py:96 msgid "correspondents" -msgstr "" +msgstr "聯繫者" #: documents/models.py:100 msgid "color" @@ -84,47 +84,47 @@ msgstr "顏色" #: documents/models.py:103 msgid "is inbox tag" -msgstr "" +msgstr "收件匣標籤" #: documents/models.py:106 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." -msgstr "" +msgstr "標記此標籤為收件匣標籤:所有新處理的文件將會以此收件匣標籤作標記。" #: documents/models.py:112 msgid "tag" -msgstr "" +msgstr "標籤" #: documents/models.py:113 documents/models.py:185 msgid "tags" -msgstr "" +msgstr "標籤" #: documents/models.py:118 documents/models.py:167 msgid "document type" -msgstr "" +msgstr "文件類型" #: documents/models.py:119 msgid "document types" -msgstr "" +msgstr "文件類型" #: documents/models.py:124 msgid "path" -msgstr "" +msgstr "位址" #: documents/models.py:129 documents/models.py:156 msgid "storage path" -msgstr "" +msgstr "儲存位址" #: documents/models.py:130 msgid "storage paths" -msgstr "" +msgstr "儲存位址" #: documents/models.py:137 msgid "Unencrypted" -msgstr "" +msgstr "未加密" #: documents/models.py:138 msgid "Encrypted with GNU Privacy Guard" -msgstr "" +msgstr "已使用 GNU Privacy Guard 進行加密" #: documents/models.py:159 msgid "title" @@ -189,27 +189,27 @@ msgstr "存檔檔案名稱" #: documents/models.py:246 msgid "Current archive filename in storage" -msgstr "" +msgstr "現時儲存空間封存的檔案名稱" #: documents/models.py:250 msgid "original filename" -msgstr "" +msgstr "原先檔案名稱" #: documents/models.py:256 msgid "The original name of the file when it was uploaded" -msgstr "" +msgstr "檔案上傳時的檔案名稱" #: documents/models.py:263 msgid "archive serial number" -msgstr "" +msgstr "封存編號" #: documents/models.py:273 msgid "The position of this document in your physical document archive." -msgstr "" +msgstr "此檔案在你實體儲存空間的位置。" #: documents/models.py:279 documents/models.py:665 documents/models.py:719 msgid "document" -msgstr "" +msgstr "文件" #: documents/models.py:280 msgid "documents" @@ -217,47 +217,47 @@ msgstr "文件" #: documents/models.py:368 msgid "debug" -msgstr "" +msgstr "偵錯" #: documents/models.py:369 msgid "information" -msgstr "" +msgstr "資訊" #: documents/models.py:370 msgid "warning" -msgstr "" +msgstr "警告" #: documents/models.py:371 paperless_mail/models.py:305 msgid "error" -msgstr "" +msgstr "錯誤" #: documents/models.py:372 msgid "critical" -msgstr "" +msgstr "嚴重" #: documents/models.py:375 msgid "group" -msgstr "" +msgstr "群組" #: documents/models.py:377 msgid "message" -msgstr "" +msgstr "訊息" #: documents/models.py:380 msgid "level" -msgstr "" +msgstr "程度" #: documents/models.py:389 msgid "log" -msgstr "" +msgstr "記錄" #: documents/models.py:390 msgid "logs" -msgstr "" +msgstr "記錄" #: documents/models.py:399 documents/models.py:464 msgid "saved view" -msgstr "" +msgstr "已儲存的檢視表" #: documents/models.py:400 msgid "saved views" @@ -265,207 +265,207 @@ msgstr "保存視圖" #: documents/models.py:405 msgid "show on dashboard" -msgstr "" +msgstr "顯示在概覽" #: documents/models.py:408 msgid "show in sidebar" -msgstr "" +msgstr "顯示在側邊欄" #: documents/models.py:412 msgid "sort field" -msgstr "" +msgstr "排序欄位" #: documents/models.py:417 msgid "sort reverse" -msgstr "" +msgstr "倒轉排序" #: documents/models.py:422 msgid "title contains" -msgstr "" +msgstr "標題包含" #: documents/models.py:423 msgid "content contains" -msgstr "" +msgstr "內容包含" #: documents/models.py:424 msgid "ASN is" -msgstr "" +msgstr "ASN 為" #: documents/models.py:425 msgid "correspondent is" -msgstr "" +msgstr "聯繫者為" #: documents/models.py:426 msgid "document type is" -msgstr "" +msgstr "文件類型為" #: documents/models.py:427 msgid "is in inbox" -msgstr "" +msgstr "在收件匣內" #: documents/models.py:428 msgid "has tag" -msgstr "" +msgstr "包含標籤" #: documents/models.py:429 msgid "has any tag" -msgstr "" +msgstr "包含任何標籤" #: documents/models.py:430 msgid "created before" -msgstr "" +msgstr "建立時間之前" #: documents/models.py:431 msgid "created after" -msgstr "" +msgstr "建立時間之後" #: documents/models.py:432 msgid "created year is" -msgstr "" +msgstr "建立年份為" #: documents/models.py:433 msgid "created month is" -msgstr "" +msgstr "建立月份為" #: documents/models.py:434 msgid "created day is" -msgstr "" +msgstr "建立日期為" #: documents/models.py:435 msgid "added before" -msgstr "" +msgstr "加入時間之前" #: documents/models.py:436 msgid "added after" -msgstr "" +msgstr "加入時間之後" #: documents/models.py:437 msgid "modified before" -msgstr "" +msgstr "修改之前" #: documents/models.py:438 msgid "modified after" -msgstr "" +msgstr "修改之後" #: documents/models.py:439 msgid "does not have tag" -msgstr "" +msgstr "沒有包含標籤" #: documents/models.py:440 msgid "does not have ASN" -msgstr "" +msgstr "沒有包含 ASN" #: documents/models.py:441 msgid "title or content contains" -msgstr "" +msgstr "標題或內容包含" #: documents/models.py:442 msgid "fulltext query" -msgstr "" +msgstr "全文搜索" #: documents/models.py:443 msgid "more like this" -msgstr "" +msgstr "其他類似內容" #: documents/models.py:444 msgid "has tags in" -msgstr "" +msgstr "含有這個標籤" #: documents/models.py:445 msgid "ASN greater than" -msgstr "" +msgstr "ASN 大於" #: documents/models.py:446 msgid "ASN less than" -msgstr "" +msgstr "ASN 小於" #: documents/models.py:447 msgid "storage path is" -msgstr "" +msgstr "儲存位址為" #: documents/models.py:448 msgid "has correspondent in" -msgstr "" +msgstr "包含聯繫者" #: documents/models.py:449 msgid "does not have correspondent in" -msgstr "" +msgstr "沒有包含聯繫者" #: documents/models.py:450 msgid "has document type in" -msgstr "" +msgstr "文件類型包含" #: documents/models.py:451 msgid "does not have document type in" -msgstr "" +msgstr "沒有包含的文件類型" #: documents/models.py:452 msgid "has storage path in" -msgstr "" +msgstr "儲存位址包含" #: documents/models.py:453 msgid "does not have storage path in" -msgstr "" +msgstr "沒有包含的儲存位址" #: documents/models.py:454 msgid "owner is" -msgstr "" +msgstr "擁有者為" #: documents/models.py:455 msgid "has owner in" -msgstr "" +msgstr "擁有者包含" #: documents/models.py:456 msgid "does not have owner" -msgstr "" +msgstr "沒有包含的擁有者" #: documents/models.py:457 msgid "does not have owner in" -msgstr "" +msgstr "沒有包含的擁有者" #: documents/models.py:467 msgid "rule type" -msgstr "" +msgstr "規則類型" #: documents/models.py:469 msgid "value" -msgstr "" +msgstr "數值" #: documents/models.py:472 msgid "filter rule" -msgstr "" +msgstr "過濾規則" #: documents/models.py:473 msgid "filter rules" -msgstr "" +msgstr "過濾規則" #: documents/models.py:584 msgid "Task ID" -msgstr "" +msgstr "任務 ID" #: documents/models.py:585 msgid "Celery ID for the Task that was run" -msgstr "" +msgstr "已執行任務的 Celery ID" #: documents/models.py:590 msgid "Acknowledged" -msgstr "" +msgstr "已確認" #: documents/models.py:591 msgid "If the task is acknowledged via the frontend or API" -msgstr "" +msgstr "如果任務已由前端 / API 確認" #: documents/models.py:597 msgid "Task Filename" -msgstr "" +msgstr "任務檔案名稱" #: documents/models.py:598 msgid "Name of the file which the Task was run for" -msgstr "" +msgstr "執行任務的目標檔案名稱" #: documents/models.py:604 msgid "Task Name" -msgstr "" +msgstr "任務名稱" #: documents/models.py:605 msgid "Name of the Task which was run" @@ -473,7 +473,7 @@ msgstr "" #: documents/models.py:612 msgid "Task State" -msgstr "" +msgstr "任務狀態" #: documents/models.py:613 msgid "Current state of the task being run" @@ -657,7 +657,7 @@ msgstr "" #: documents/models.py:967 paperless_mail/models.py:238 msgid "assign this correspondent" -msgstr "" +msgstr "指派這個聯繫者" #: documents/models.py:975 msgid "assign this storage path" @@ -1128,7 +1128,7 @@ msgstr "" #: paperless_mail/models.py:88 msgid "Do not assign a correspondent" -msgstr "" +msgstr "不要指派聯繫者" #: paperless_mail/models.py:89 msgid "Use mail address" @@ -1140,7 +1140,7 @@ msgstr "" #: paperless_mail/models.py:91 msgid "Use correspondent selected below" -msgstr "" +msgstr "使用以下已選擇的聯繫者" #: paperless_mail/models.py:101 msgid "account" @@ -1220,7 +1220,7 @@ msgstr "" #: paperless_mail/models.py:228 msgid "assign correspondent from" -msgstr "" +msgstr "指派聯繫者從" #: paperless_mail/models.py:242 msgid "Assign the rule owner to documents" diff --git a/src/paperless/version.py b/src/paperless/version.py index 27a431916..b61c1a526 100644 --- a/src/paperless/version.py +++ b/src/paperless/version.py @@ -1,6 +1,6 @@ from typing import Final -__version__: Final[tuple[int, int, int]] = (2, 1, 2) +__version__: Final[tuple[int, int, int]] = (2, 1, 3) # Version string like X.Y.Z __full_version_str__: Final[str] = ".".join(map(str, __version__)) # Version string like X.Y