From b21970fd53d501817de53ccb74655ea2193bfd1d Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon, 5 Dec 2022 01:25:11 -0800 Subject: [PATCH] Merge branch 'dev' commit fb9d3f736bebadd528aa47fb3a3c643f3f6d8574 Merge: 4d4d5453 049dc179 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sun Dec 4 16:47:58 2022 -0800 Merge pull request #2000 from paperless-ngx/feature-frontend-paperless-mail Feature: frontend paperless mail commit 4d4d545343b8f44cb4377bd4292948b0a6428a87 Merge: 2704bcb9 4b31e5d0 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Sun Dec 4 16:34:41 2022 -0800 Merge pull request #848 from p-h-a-i-l/feature-consume-eml Feature ability to consume mails and eml files commit 049dc17902c11456323e3a68327963dfd3cd5f1c Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Dec 4 16:33:07 2022 -0800 Moves where the mail views live and puts the ordering on those commit 4b31e5d0b46639c5cb68005149e2e2f0dc13ca94 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Dec 4 14:00:59 2022 -0800 Fixes my broken formatting commit 8076ebd78ca61b8b4369ed03d462962e03b76708 Merge: fe2db4db 2704bcb9 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Dec 4 13:55:46 2022 -0800 Merge remote-tracking branch 'upstream/dev' into feature-consume-eml commit 2704bcb979d7fa6b357f008413394f24dc950cc0 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Dec 4 13:06:18 2022 -0800 Resets to -dev versioning commit 59f6074093e7156661044941b571a6d1fca5524f Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Dec 4 12:58:03 2022 -0800 Bumps version to 1.10.2 commit b1da7f34913fc247d1b4c333cdb98547f5816ff9 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Dec 4 12:57:19 2022 -0800 Probably fixes the changelog step not working commit adde88e7b90ff218eff7ae98dd21eb06c945d173 Merge: a8f3c4be 8e876ef2 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Dec 4 12:55:55 2022 -0800 Merge branch 'dev' commit 8e876ef2d15b3dd5fe055e3b389e1ccb532b2017 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Dec 4 10:20:48 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit 2ea0f83a91cb666710e782a53db5aba798c6f98e Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 05:12:02 2022 -0800 New translations messages.xlf (Italian) [ci skip] commit 05d8ea5a9db8636b11e546cb2eec984126de77d0 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:09:05 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit 967248233fcd1b17a0a4e0d037cd67910c666ab1 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:09:04 2022 -0800 New translations messages.xlf (French) [ci skip] commit b4c4b9fb6a608473aac85f37198e0d9786d7ed39 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:09:03 2022 -0800 New translations messages.xlf (Spanish) [ci skip] commit adb6483abc4d68770019a5c8b6e05db4d8ee1d82 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:09:01 2022 -0800 New translations messages.xlf (Arabic) [ci skip] commit 908db55bb7545ab91af4e28db0a2b35fb9f2b490 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:09:00 2022 -0800 New translations messages.xlf (Belarusian) [ci skip] commit 610f20de286f26535c0dd21b322c4c9e386a7348 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:59 2022 -0800 New translations messages.xlf (Czech) [ci skip] commit b2513a5cde2e0b590f70d2076b8a41c906224295 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:57 2022 -0800 New translations messages.xlf (Danish) [ci skip] commit bfa1c13d01838886b44525e8e4a444a4f8f977ab Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:56 2022 -0800 New translations messages.xlf (Finnish) [ci skip] commit 12aaff431f64229037eefbcb93d7996787b54ddf Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:55 2022 -0800 New translations messages.xlf (Hebrew) [ci skip] commit 547e5ea55e86548142abe348bb26b00ebaaeee9c Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:54 2022 -0800 New translations messages.xlf (Italian) [ci skip] commit c301127096b6a70ca9f6f595ed9183ecb01dad16 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:52 2022 -0800 New translations messages.xlf (Dutch) [ci skip] commit 19147855e715d29bce9d8c0312fd596932276409 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:51 2022 -0800 New translations messages.xlf (Romanian) [ci skip] commit 4e7c7ea1d66be890845f899efe7c3fef2736c038 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:49 2022 -0800 New translations messages.xlf (Norwegian) [ci skip] commit fcf8a49160702f9cb50552fefccfa20011e6bdca Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:48 2022 -0800 New translations messages.xlf (Portuguese) [ci skip] commit c6d658a954adca50c71016305e5cf652bf7c16da Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:47 2022 -0800 New translations messages.xlf (Russian) [ci skip] commit a78cd6526ca4955b56823fdbe1760978c1fa3e13 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:45 2022 -0800 New translations messages.xlf (Slovenian) [ci skip] commit bf895b54f4de8ff686dd308e38fc4327437de48a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:44 2022 -0800 New translations messages.xlf (Swedish) [ci skip] commit e5f84ef5837508071147f01bfde5d707a1fe3588 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:43 2022 -0800 New translations messages.xlf (Turkish) [ci skip] commit 8c690a9a51ea3f11ec9b560a544b6280f4c1b4e7 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:41 2022 -0800 New translations messages.xlf (Chinese Simplified) [ci skip] commit 56526b970ad2539133196ac832750fee7f4dbb73 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:40 2022 -0800 New translations messages.xlf (Portuguese, Brazilian) [ci skip] commit 94fbf929167049cd0319f89c4f9b7d017297f0c9 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:38 2022 -0800 New translations messages.xlf (Croatian) [ci skip] commit 37f5e46d092617708578b19ef1968cd98a48a91a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:37 2022 -0800 New translations messages.xlf (Luxembourgish) [ci skip] commit 38be817637ebc06a6237900241ccb23110fcc5bf Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:36 2022 -0800 New translations messages.xlf (Polish) [ci skip] commit 17303f41dadfd1ad8719a613e5e2d94284fcd492 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Dec 3 02:08:34 2022 -0800 New translations messages.xlf (German) [ci skip] commit 55ef0d4a1b62c3abe8500cad97ddeecf9f746b84 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Dec 4 08:44:35 2022 -0800 Fixes language code checks around two part languages commit a8f3c4be5494303ed16b04ff0b4a78325302f558 Merge: fa62ae82 1b9de2be Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 18:47:09 2022 -0800 Merge pull request #1947 from alexander-bauer/helm Take ownership of k8s-at-home Helm chart, commit 1b9de2be5ab799c74953068e91c06c8fa57f5275 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 18:46:19 2022 -0800 Use checkout v3 commit 0e8265f1aec188ea245b8a8aa4d831c95e9dd410 Merge: ea38eb01 5b45a140 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 18:44:28 2022 -0800 Merge pull request #2109 from paperless-ngx/fix/redis-socket-parsing Bugfix: Redis socket compatibility didn't handle URLs with ports commit 5b45a140b93c27b10302b2c3577fdcfd81b3a8b3 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sat Dec 3 18:30:21 2022 -0800 Fixes issue when the Redis URL also specifies a port commit 72fb9a475d1f48c5e3e6ac9a057e65989a0ddbf5 Author: Alexander Bauer Date: Thu Nov 10 02:24:04 2022 +0000 Ignore end-of-lines on generated Chart README commit bf97f5807f6f5458ebe9d3b8336cf1b32d1f440c Author: Alexander Bauer Date: Thu Nov 10 02:21:29 2022 +0000 Ignore non-yaml Helm chart template commit a707818b4da0e477026c39ddd9a2081513995d7b Author: Alexander Bauer Date: Thu Nov 10 01:54:35 2022 +0000 Change Helm chart releaser to use version tags only commit fb46c1b96a1d72cc77b795df1bbbc1cbd5edfadd Author: Alexander Bauer Date: Thu Nov 10 01:52:02 2022 +0000 Ignore generated Helm chart README from prettier commit 3226d8b25b7af149f8dbf69525cff9015e3676dd Author: Alexander Bauer Date: Tue Nov 8 00:46:27 2022 +0000 fixup! Add mostly-unchanged Helm chart from k8s-at-home commit 5c4363cbea46630a682ed5f10bf7146f0fa24950 Author: Alexander Bauer Date: Tue Nov 8 00:24:04 2022 +0000 Add mostly-unchanged Helm chart from k8s-at-home - Add the chart from k8s-at-home with some modifications - Add the Apache 2.0 license to the new charts/paperless-ngx subdirectory, the license under which the chart was distributed by k8s-at-home. I believe the chart will have to maintain this license. - Update the maintainers section and contact information to point to Paperless-ngx. - Regenerate the README (using helm-docs) - Add a GitHub actions configuration to publish the chart using GitHub pages. This makes the GitHub Pages page rendered by this repository usable as a Helm repository, without affecting potential future uses of the Pages site. These are in response to discussion #1790. commit fa62ae820bdeb402f751e91f1f4d6b17b8248a21 Merge: bcc029a2 17891baf Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 14:19:36 2022 -0800 Merge pull request #2106 from tooomm/docs/edit Docs: Some more small MkDocs updates commit 17891bafaf8bd7dfcbfc949efddb6bd2d61ec62b Author: tooomm Date: Sat Dec 3 20:02:40 2022 +0100 lint commit 15fdadadef30b40811dcac54bf9fabbde277e759 Author: tooomm Date: Sat Dec 3 19:36:49 2022 +0100 open demo in new page commit ce9f604d81820a4fba83ec38e5f58e6317165814 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 09:29:34 2022 -0800 Explicit default ordering for rule / account views commit 4f876db5d1d1407a8660aa1c58322fc8e36701e2 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Nov 28 21:38:52 2022 -0800 prevent loss of unsaved changes to settings on tab nav commit 5e5f56dc67c0ba6b516a9ec7e27ca3bf653df548 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Nov 28 20:39:03 2022 -0800 Re-org where some of the new classes are found commit 93fab8bb95661343981fbcab055de3bae9482702 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Nov 28 12:53:20 2022 -0800 Apply code suggestions from @stumpylog commit 35ca2195feb1c32633d88da5972cc5652bc3ebf2 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Nov 28 15:51:39 2022 -0800 frontend mail rule validation Display non-field validation errors, hide action param field if not needed commit 7ace66d7fd9f75ed1b66d7242622b8dee478534c Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Nov 28 13:58:37 2022 -0800 fix edit dialog getters commit 4f9a31244b3916b7205388fcae46b2d59cca10f7 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Nov 18 20:23:40 2022 -0800 Add settings routing commit 14cf4f709521123fcb8c9472c5f6b3c663ffc5c8 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Nov 18 19:38:49 2022 -0800 Update frontend strings commit 8bd7c2782621c66703aff65dcf95704a83d72bf9 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Nov 18 17:11:15 2022 -0800 Hide order parameter, fix imap port commit 8c4f486fe984e1b5ebd19e314c49ae7277ae7178 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Nov 18 14:22:07 2022 -0800 API mail rule & account tests and fix use of assign_tags commit 284941444519e44b2d4322e0af2c9edd408d2b7a Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Nov 18 14:21:31 2022 -0800 one-way imap password setting via API, ObfuscatedPasswordField commit ea1ea0816fbd4d17d9c62fe21e983f1fa62ca4d9 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Nov 18 14:10:17 2022 -0800 Fix mail account / rule delete commit 52d3a8703c383d414298f8814a1bc3957ce89ec5 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Nov 12 15:14:58 2022 -0800 Dynamically load mail rules / accounts settings commit 4cb4d6adcd33c917c370fd480687fdcecf09230b Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Nov 12 15:15:59 2022 -0800 update settings tests to not wait on data which is now on-demand commit 24444237f2216ce42e1b2484de7e56296fe62a63 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Nov 12 14:46:57 2022 -0800 dynamic loading of settings tab contents commit 40c8629aef6f0b971d17a190ad48e6c6680e4d30 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Nov 10 21:04:29 2022 -0800 Update welcome tour, move admin button commit 98cdf614a576618a96035ff7dcc93849199ea52d Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed Nov 9 19:59:35 2022 -0800 Mail form tweaks Include add button Include add button commit 2eb2d99a913f4b1dcb8a2d55393e5e96794cb17b Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed Nov 9 03:43:57 2022 -0800 Update frontend fixtures & tests for compatibility commit 18ad9bcbf2865f27ca8a04bc37b210c9c8c3eb86 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 8 12:18:47 2022 -0800 Working mail rule & account edit commit 997bff4917d5ef8c9426d3751927b4afcf9d2e6f Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed Nov 9 02:40:45 2022 -0800 Update deprecated edit-dialog rxjs commit 78f9a8089585dd24ea53cf0ac2492de54083ecc7 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 8 12:09:16 2022 -0800 mail account + rule deletion commit 9231df7a4a9e0a4df28b11a5c4bd34fbcf9defe3 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 8 11:50:57 2022 -0800 Mail rule edit dialog commit 6f25917c86a5152ae1ec3988cd42f4dc7b76df66 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 8 11:11:35 2022 -0800 Mail account edit dialog commit c41d1a78a86d1ac585ac03e424d733087ca3fe09 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 8 10:53:41 2022 -0800 remove unused toastService from edit dialogs and add confirmation commit c3331086d55661f9f1a973194cef951d2ccd05d9 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 8 03:39:54 2022 -0800 Basic data retrieval commit 6bd9ccd8f69e163acb522833bb65b9a07763b1ce Author: tooomm Date: Sat Dec 3 18:30:02 2022 +0100 update default edit path commit 68c7cecb07967b5fbfdc2fd0f900a938a5225b14 Author: tooomm Date: Sat Dec 3 18:29:14 2022 +0100 add mkdocs site to gitignore commit bcc029a2c763e8dcc759a815cb7332af1b90bbb9 Merge: 9d418055 1727eb00 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 09:00:02 2022 -0800 Merge pull request #2104 from paperless-ngx/docs-cleanup Chore: Cleans up documentation links commit ea38eb01b21844aadc99956b54cd3b65ffd458a1 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Fri Dec 2 13:54:15 2022 -0800 Adds support for database number specification commit 01d070b882ef9027bef9a046852c2060119edd5d Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Fri Dec 2 09:34:59 2022 -0800 Adds a layer to translate between differing formats of socket based Redis URLs commit 1727eb00cc7f98a52125a6ebdb87dad16483de3a Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Fri Dec 2 19:34:43 2022 -0800 Cleans up a number of internal links commit 9d4180553c972a813e4f83d4d65858c989eb20b5 Merge: 7c614264 8049af4b Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 07:58:12 2022 -0800 Merge pull request #2102 from tooomm/patch-1 Fix doc links in contributing commit 8049af4b22ae1cd51d3c122eb3afd9c30beea24d Author: tooomm Date: Sat Dec 3 14:38:55 2022 +0100 Fix doc links in contributing commit 7c6142643d054228e0902a213abdea26ff0ad063 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 02:08:51 2022 -0800 Update more docs references commit 2e8706f4e2fb97a70494029354c359db356c9d64 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 02:05:49 2022 -0800 Update frontend translation strings commit d39d32d55573d2790524db396a35ce92cfe8b695 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 02:04:30 2022 -0800 Fix docs references commit 6f52945449d9ddda8167597acc7d5f9165fd9d65 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 01:47:04 2022 -0800 docs index formatting error commit 37025297b5d03df42ac98a7b82d04f7502ab6db9 Merge: aa023ea2 dc9e9e3b Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 01:33:31 2022 -0800 Merge pull request #2095 from paperless-ngx/update-readme-doc-links Documentation: Update docs links and screenshot in readme, add favicon commit aa023ea2e355b5f40fd5d5c1f80efdb45987c09c Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Dec 3 01:30:07 2022 -0800 correct docs deploy domain commit 78bf0b63a5ca666742970eb08704284550805e44 Merge: 29391c1c a96ecd67 Author: Felix E Date: Sat Dec 3 09:10:20 2022 +0100 Merge pull request #2087 from Ricks-ha/main Add examples to URL and TIME_ZONE commit dc9e9e3b48b644fb598c20e3949de09b666e31ef Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Dec 2 20:06:51 2022 -0800 add favicon commit ab29c49b7a6855a3884ed1ffa1e00010924fc99f Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Dec 2 19:09:19 2022 -0800 Update docs links and screenshot in readme commit 1c0ac474b85889b0c75875323734dc05b4f5ddf9 Merge: 25fb8d9c 29391c1c Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Fri Dec 2 19:05:28 2022 -0800 Merge branch 'main' into dev commit 29391c1c7b6c3adbd96a09d66b5a2b02e392b050 Merge: 58a01a57 69383497 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Dec 2 15:22:39 2022 -0800 Merge pull request #2067 from paperless-ngx/material-docs [WIP] Feature: Move docs to material-mkdocs commit 693834971c7413098321800b150c56417e7142c6 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 20:00:23 2022 -0800 Add v1.10.1 changelog commit 97376d4b7229b9cdd05d151c3b61a404053c59f9 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Dec 2 09:09:29 2022 -0800 update ci for documentation build vs deploy commit 3ee1d2a9a9a3a78e9254850f0d4a9f98664cc5dd Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 29 21:20:45 2022 -0800 Add changes from #2069 commit 605f885e19136ec1c728e6c8497c0ac76eaa285e Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 29 12:49:23 2022 -0800 Move docs to material-mkdocs commit 25fb8d9c3be66e778f6215fc5c4b1377b9b526b9 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Dec 2 08:30:42 2022 -0800 Update dev version string commit a96ecd673be07db1304d76037faec056ae170b41 Author: Ricks-ha Date: Fri Dec 2 13:27:57 2022 +0100 Add examples to URL and TIME_ZONE commit 58a01a57ee6e018918d7b4d1d01e0d36cb351a50 Merge: a96f79f6 c18fc03e Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Dec 2 03:36:55 2022 -0800 Merge pull request #2082 from paperless-ngx/v1.10.1-changelog Chore: Add v1.10.1 changelong commit c18fc03ef3c684075ec4ade333c20bc792282bfe Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 20:00:23 2022 -0800 Add v1.10.1 changelong commit a96f79f6a33c08d090ec33a2021996cd56df407d Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 18:54:00 2022 -0800 Bump version to 1.10.1 commit d6f1d004a34d34b7e974393820b04d021bcca41d Merge: 88cf6ef8 da72d357 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 18:52:35 2022 -0800 Merge branch 'dev' commit da72d3571be02b71ffc5650d0031e4ba2143cc78 Merge: 8241da0e 86592928 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 18:52:06 2022 -0800 Merge pull request #2050 from paperless-ngx/l10n_dev New Crowdin updates commit 8241da0eb3c1c105beecdb4204276d139a514a43 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 17:01:22 2022 -0800 fix broken npm package-lock commit 51562667bfe3f05e185ff878268d04af5cd63cdf Merge: 1aee2988 97eeae65 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 16:40:07 2022 -0800 Merge pull request #2076 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/tslib-2.4.1 Bump tslib from 2.4.0 to 2.4.1 in /src-ui commit 97eeae65a3a0590a95e2ab77afd94a9ba2b48319 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri Dec 2 00:39:26 2022 +0000 Bump tslib from 2.4.0 to 2.4.1 in /src-ui Bumps [tslib](https://github.com/Microsoft/tslib) from 2.4.0 to 2.4.1. - [Release notes](https://github.com/Microsoft/tslib/releases) - [Commits](https://github.com/Microsoft/tslib/compare/2.4.0...2.4.1) --- updated-dependencies: - dependency-name: tslib dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] commit 1aee2988f739634b49abcd84a31860301fb19dbd Merge: a63a8dd4 6f0077ef Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 16:39:24 2022 -0800 Merge pull request #2079 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/angular-builders/jest-14.1.0 Bump @angular-builders/jest from 14.0.1 to 14.1.0 in /src-ui commit a63a8dd488a8af00b4783ec40a53600fe1689b42 Merge: 06a9df6d 39be68a1 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 16:38:38 2022 -0800 Merge pull request #2078 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/jest-preset-angular-12.2.3 Bump jest-preset-angular from 12.2.2 to 12.2.3 in /src-ui commit 06a9df6dbd10f7c4931a1dec4e81aee32625647d Merge: 49933bb5 7d7d9630 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 16:37:25 2022 -0800 Merge pull request #2080 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/ngx-file-drop-14.0.2 Bump ngx-file-drop from 14.0.1 to 14.0.2 in /src-ui commit 49933bb5a82dbf143acdd004493c03a6e0b2450c Merge: 02c782a1 ac69babf Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 16:18:07 2022 -0800 Merge pull request #2077 from paperless-ngx/dependabot/npm_and_yarn/src-ui/dev/ngneat/dirty-check-forms-3.0.3 Bump @ngneat/dirty-check-forms from 3.0.2 to 3.0.3 in /src-ui commit 7d7d9630c193c119c90235751339b34142ea6dc8 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu Dec 1 20:03:32 2022 +0000 Bump ngx-file-drop from 14.0.1 to 14.0.2 in /src-ui Bumps [ngx-file-drop](https://github.com/georgipeltekov/ngx-file-drop) from 14.0.1 to 14.0.2. - [Release notes](https://github.com/georgipeltekov/ngx-file-drop/releases) - [Changelog](https://github.com/georgipeltekov/ngx-file-drop/blob/master/CHANGELOG.md) - [Commits](https://github.com/georgipeltekov/ngx-file-drop/compare/v14.0.1...v14.0.2) --- updated-dependencies: - dependency-name: ngx-file-drop dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] commit 6f0077efac2cb8d7ecf28fa1f1cb8464f26bbb8c Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu Dec 1 20:03:05 2022 +0000 Bump @angular-builders/jest from 14.0.1 to 14.1.0 in /src-ui Bumps [@angular-builders/jest](https://github.com/just-jeb/angular-builders/tree/HEAD/packages/jest) from 14.0.1 to 14.1.0. - [Release notes](https://github.com/just-jeb/angular-builders/releases) - [Changelog](https://github.com/just-jeb/angular-builders/blob/master/packages/jest/CHANGELOG.md) - [Commits](https://github.com/just-jeb/angular-builders/commits/@angular-builders/jest@14.1.0/packages/jest) --- updated-dependencies: - dependency-name: "@angular-builders/jest" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] commit 39be68a1a4dc7a5dc7a29a416c4eb62b34f86262 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu Dec 1 20:02:39 2022 +0000 Bump jest-preset-angular from 12.2.2 to 12.2.3 in /src-ui Bumps [jest-preset-angular](https://github.com/thymikee/jest-preset-angular) from 12.2.2 to 12.2.3. - [Release notes](https://github.com/thymikee/jest-preset-angular/releases) - [Changelog](https://github.com/thymikee/jest-preset-angular/blob/main/CHANGELOG.md) - [Commits](https://github.com/thymikee/jest-preset-angular/compare/v12.2.2...v12.2.3) --- updated-dependencies: - dependency-name: jest-preset-angular dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] commit ac69babfce90f55486749ce32c56bf29fba17b5e Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu Dec 1 20:02:11 2022 +0000 Bump @ngneat/dirty-check-forms from 3.0.2 to 3.0.3 in /src-ui Bumps [@ngneat/dirty-check-forms](https://github.com/ngneat/dirty-check-forms) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/ngneat/dirty-check-forms/releases) - [Changelog](https://github.com/ngneat/dirty-check-forms/blob/master/CHANGELOG.md) - [Commits](https://github.com/ngneat/dirty-check-forms/compare/v3.0.2...v3.0.3) --- updated-dependencies: - dependency-name: "@ngneat/dirty-check-forms" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] commit 02c782a1273ff7411f53a27c3b2f4c807f4f1358 Merge: 4e90fda8 9b602a4b Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Dec 1 08:19:59 2022 -0800 Merge pull request #2073 from paperless-ngx/fix-frontend-tasks-display Fix: frontend tasks display in 1.10.0 commit 4e90fda80f651d67016795d8b273f34a44da880f Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Tue Nov 29 20:06:56 2022 -0800 Expands documentation around the permissions of the custom scripts and the folder commit 88e3e556a1ded458ea2172cbc329a3ac54470b8b Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Tue Nov 29 20:05:08 2022 -0800 Fixes the custom scripts not running as root commit 88cf6ef843ffe428e164f3c7c57cdf1a856c3180 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed Nov 30 15:14:21 2022 -0800 add demo badge commit 9b602a4bf016ffa6c7731269f8b3a358b1a1fba0 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed Nov 30 13:55:51 2022 -0800 Fix frontend tasks display commit fe2db4dbf7bbc21b287fd72cd124545160eaa7c0 Author: phail Date: Wed Nov 30 10:16:39 2022 +0100 adapt compose file for eml parsing commit 47c88a6bdd154a343b64ca8ae5073fa58897fa7b Merge: 4aa31859 a3bc3b78 Author: phail Date: Wed Nov 30 10:10:57 2022 +0100 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit a3bc3b78d53af7cb58456fe4b3de40258a411744 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Tue Nov 29 14:34:12 2022 -0800 Also display the container logs commit fed7d3e9933202c6ccdc2de7c1203a7bf2af69a0 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Tue Nov 29 13:59:48 2022 -0800 Use docker compose to start and stop containers which match directly to our command overrides commit 3a74f24e49e2e0aeaf17897d2fe504ae3f06377c Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Tue Nov 29 12:44:53 2022 -0800 Adds libatomic1 for supporting armv7 better commit 52afab39cfbd38234aa9c69cd0e1554702c0d991 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Tue Nov 29 12:16:51 2022 -0800 Organizes the system packages a little bit more commit 8659292852acaeb07df4a0cadc8cf09649b93961 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Tue Nov 29 00:29:45 2022 -0800 New translations django.po (Norwegian) [ci skip] commit ce73f159fd23159531c5786b381d4407c6550df9 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Mon Nov 28 14:13:54 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit 71382e9c620d25cca435a234c9a91fb7d352dab2 Merge: 5d3a6e23 a1a802fc Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Nov 28 14:05:57 2022 -0800 Merge pull request #2062 from paperless-ngx/fix/2053-long-names-too-quiet Bugfix: Don't silence an exception when trying to handle file naming commit a1a802fc92359e2686497f32e53fb6247ad78886 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Mon Nov 28 13:44:17 2022 -0800 Don't silence an exception when trying to handle file naming commit 4200fc610dbed1a70fecbf8ade96ea8501d69e12 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Mon Nov 28 13:17:22 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit 32d212cd9f11962346f828bdb6935c522bc38a81 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Mon Nov 28 11:17:07 2022 -0800 New translations messages.xlf (German) [ci skip] commit 5d3a6e230d5e673c4ce61945098c68222b3b760f Merge: b33fcc11 f0497e77 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Nov 28 11:04:44 2022 -0800 Merge pull request #2057 from paperless-ngx/fix/2044-lang-code-diffs Bugfix: Some tesseract languages aren't detected as installed. commit b33fcc117e03b768d4fbfa7ee34470fccf2c940b Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Mon Nov 28 09:25:03 2022 -0800 Transition to a maintained upload release assert commit e96d65f9451a1b92aaec0085654c21a50d581adc Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Mon Nov 14 15:38:35 2022 -0800 Allows parsing of WebP format images commit cfeed0ce6eec797dc122d692bda7329d60d7045d Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Mon Nov 28 08:30:32 2022 -0800 New translations django.po (Polish) [ci skip] commit b89ecf7d7764c4b88c1f4caccc161c786aa306d4 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Mon Nov 28 05:28:39 2022 -0800 New translations messages.xlf (Luxembourgish) [ci skip] commit 5ca25d44baa9e086781d7c7d03bdb608839ab093 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Mon Nov 28 04:27:31 2022 -0800 New translations messages.xlf (Luxembourgish) [ci skip] commit 1e11c12d96f79b9822d96a419574b6784a41770e Merge: e74d7dad 3e22e8e0 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sun Nov 27 21:16:50 2022 -0800 Merge branch 'main' into dev commit 3e22e8e0b96a3d072c85c735639176bd5b23114f Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 27 19:22:59 2022 -0800 prepends the latest changelog commit dba45f93a4de843edba2bfb6641a14ce3f269fe4 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 27 19:22:03 2022 -0800 Fixes the pre-commit command commit 18f3f44ae918dddaed969dc563db8d7895a3148f Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:25 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit 85a6a271dc9608518ae584a1a130ea32cef1aa0b Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:23 2022 -0800 New translations messages.xlf (French) [ci skip] commit abb515d4ea0ef75008b6b90294185ff0b1ccb2d6 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:22 2022 -0800 New translations messages.xlf (Spanish) [ci skip] commit 309d1f2b6785c9b8905aea1d28a1dc7804a712a0 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:21 2022 -0800 New translations messages.xlf (Arabic) [ci skip] commit fa2f09bc4b279e22df9679ce1b6801eaa9bc9177 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:19 2022 -0800 New translations messages.xlf (Belarusian) [ci skip] commit c51590cd1264835ce7cadb43b3c4c70e4712a36d Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:18 2022 -0800 New translations messages.xlf (Czech) [ci skip] commit 8e01406acfed5d06b8904f68bcebe933e938ca54 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:17 2022 -0800 New translations messages.xlf (Danish) [ci skip] commit 7cce2f0fe60b82c50159d25cb91bf2e87e0cc6c0 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:16 2022 -0800 New translations messages.xlf (Finnish) [ci skip] commit 95091c2f393808870c91038c54036579eaa024c6 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:14 2022 -0800 New translations messages.xlf (Hebrew) [ci skip] commit 4a0aa12bd99d1c99dfbf6ebf8751038f1d933169 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:13 2022 -0800 New translations messages.xlf (Italian) [ci skip] commit 9a0329746a07b7307f7ddd868b4259cce38532cb Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:11 2022 -0800 New translations messages.xlf (Dutch) [ci skip] commit 8392a6fd4a3777ae6d432af7c4a39e62e744511a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:10 2022 -0800 New translations messages.xlf (Romanian) [ci skip] commit 8fa18bb8a6c2065fed25f35cbb047cc1e2231979 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:09 2022 -0800 New translations messages.xlf (Norwegian) [ci skip] commit 0095b593fb7ec30ce33a57931bc1c0a0ab3a87de Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:08 2022 -0800 New translations messages.xlf (Portuguese) [ci skip] commit b1e5135e2126a133e1ccdb10c703996e4e20860e Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:05 2022 -0800 New translations messages.xlf (Russian) [ci skip] commit e88755e7ac6b7824001ec6c7f0ca4932b9412182 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:04 2022 -0800 New translations messages.xlf (Slovenian) [ci skip] commit c58294729132949a6f0b4cf0baba0bbabb60254d Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:02 2022 -0800 New translations messages.xlf (Swedish) [ci skip] commit 98fe3a2cb71a2345e4c7d29eaec4428095ba5857 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:58:01 2022 -0800 New translations messages.xlf (Turkish) [ci skip] commit 61647606fa2d571c82f93a3f0c6f50894e314f23 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:57:59 2022 -0800 New translations messages.xlf (Chinese Simplified) [ci skip] commit 95a1e5c6454a52d446b6b88f7b9721b247558300 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:57:58 2022 -0800 New translations messages.xlf (Portuguese, Brazilian) [ci skip] commit 8ead77f128eec14ae790bbd08880cd295a58621a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:57:57 2022 -0800 New translations messages.xlf (Croatian) [ci skip] commit b9e9e82f33122d4e501e906cdcb6f68131bea0cd Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:57:55 2022 -0800 New translations messages.xlf (Luxembourgish) [ci skip] commit 487fd3a5dd4eafa8ccad1fdd7d0df0532294f273 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:57:54 2022 -0800 New translations messages.xlf (Polish) [ci skip] commit 657786a2febe3e57b16ee021b1e968706e426a7a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sun Nov 27 17:57:52 2022 -0800 New translations messages.xlf (German) [ci skip] commit e74d7dadfb69d5b5c7e77342cb81608a6a55845a Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 27 17:43:46 2022 -0800 Adds the -dev back to the UI version commit a2937cd54d1ceb60bcecdfa70edc19b769f01a26 Merge: 9b01aa92 7b3ce628 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 27 17:42:41 2022 -0800 Merge branch 'main' into dev commit 7b3ce6289fa2a3588ea92af9988e7ef034237c40 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 27 17:21:12 2022 -0800 Bumps version number to 1.10.0 commit a16e8324bef12eed7ecab64d5b814aa514cf9b3c Merge: 34a0111f 39de531d Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 27 17:18:08 2022 -0800 Merge pull request #1960 from paperless-ngx/beta [Beta] Paperless-ngx v1.10.0 Release Candidate commit 39de531df5baed7ef3b2d6eec05db0b6eb87f987 Merge: 4764d4fd c9d6c208 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sun Nov 27 14:47:14 2022 -0800 Merge pull request #2041 from paperless-ngx/l10n_dev New Crowdin updates commit 4764d4fd2b774857d4651e71456d7c0bc3a6cc13 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Nov 26 12:28:51 2022 -0800 New translations django.po (German) [ci skip] commit e147d4571f43a47c0312c4170f62c1746543b130 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Nov 26 09:54:00 2022 -0800 New translations django.po (German) [ci skip] commit dc9aaa64727e5f1cdb9f26b8da8c34ccb822522e Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Tue Nov 22 15:21:31 2022 -0800 New translations django.po (German) [ci skip] commit 8a061c4ac219a60720d5ec6ca20aec8e13a54a10 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Tue Nov 22 15:21:30 2022 -0800 New translations messages.xlf (German) [ci skip] commit d051c5c2824dd7cf01e3a0d068264e2340e26808 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Nov 12 08:48:48 2022 -0800 Remove ar-SA commit 9e60810a8bc3c7b570f4157080ec77a6f21ed3ba Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Nov 12 08:33:08 2022 -0800 New translations messages.xlf (Arabic) [ci skip] commit 96ee7990b2bc3ac1ebfe10d1048a4dcf697da3f1 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Fri Nov 11 13:59:54 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit 224bfeb72e18256b79afc5eff4894a30331b8090 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Fri Nov 11 13:04:01 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit f0497e77449bcb18ede3452e26fc001dfd3feaf4 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 27 08:28:22 2022 -0800 Fixes how a language code like chi-sim is treated in the checks commit c9d6c208afe5d56035cd2f10c51ed530a8371c40 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Nov 26 12:28:51 2022 -0800 New translations django.po (German) [ci skip] commit 9f2b8b1734ece2a5c51be743760098b33c9e9bfe Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Nov 26 09:54:00 2022 -0800 New translations django.po (German) [ci skip] commit a04b9e37552b7a5f4b6f26078c38fc93041d1110 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Tue Nov 22 15:21:31 2022 -0800 New translations django.po (German) [ci skip] commit a81d4c5e9dad6e8f49c20c316513cca27d99a032 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Tue Nov 22 15:21:30 2022 -0800 New translations messages.xlf (German) [ci skip] commit 2140d4209825252bd9106ac9ade6dc1ba4e507dd Merge: a5283525 2a5dc4de Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 22 14:35:34 2022 -0800 Merge pull request #2025 from paperless-ngx/fix-redo-ocr-message Add info that re-do OCR doesnt automatically refresh content commit 43325371fc79726f2fbad6b00d24b4e4614fea9b Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Nov 12 08:48:48 2022 -0800 Remove ar-SA commit d10721089e21d6a2c16f1da8b63e7e19ee22788d Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Nov 12 08:33:08 2022 -0800 New translations messages.xlf (Arabic) [ci skip] commit f1a1a2da8b89a6c30a837e8d96d8efccb678a05b Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Fri Nov 11 13:59:54 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit 612e0a1163b8fb1143108b8615097f05f0a81b15 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Fri Nov 11 13:04:01 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit 2a5dc4de3865823dca78f6042a9cbfb526950667 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 22 14:16:04 2022 -0800 Add info that re-do OCR doesnt automatically refresh content commit a5283525bc6b26f4f7b03f09ea1fe5e43cef440a Merge: f0155565 de98d748 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Nov 22 13:53:08 2022 -0800 Merge pull request #2023 from paperless-ngx/fix/2019-create-date Bugfix: Fix created_date being a string commit de98d748a9548e420be3cef3fde58eb4ce777940 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Tue Nov 22 10:11:27 2022 -0800 If override_date is provided, coerce it into a datetime commit f015556562ffa291f41076f49938111a674f3a60 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Mon Nov 21 14:56:14 2022 -0800 Adds a test to cover this edge case commit b897d6de2e3fbd26c6b6bcd9c09932e99e14fead Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Mon Nov 21 14:45:20 2022 -0800 Don't use the sidecar file when redoing the OCR, it only contains new text commit 54f20b381e675ddab881e16a9a8ee2181591e979 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Mon Nov 21 12:59:14 2022 -0800 Documents some issues and the required manual fixes for MariaDB commit c0d42480216bc4df0caed097713f960f644e4d76 Merge: 27f7f0a9 870e295a Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Nov 21 22:19:02 2022 -0800 Merge pull request #1973 from paperless-ngx/l10n_dev New Crowdin updates commit 870e295aaeb0950cebed77e651df786b321c313b Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Mon Nov 21 21:43:54 2022 -0800 New translations messages.xlf (German) [ci skip] commit 4aa318598fd0dc6c5d4e08dd2a13e7bf614511ec Author: phail Date: Sun Nov 20 23:26:20 2022 +0100 add test comments commit 00f39d8b581c358f2484680275222f6ad909758c Author: phail Date: Sun Nov 20 22:49:42 2022 +0100 add test comments commit 0b1a16908fbbb88728301fa708d221a9138539ce Author: phail Date: Sun Nov 20 20:33:07 2022 +0100 Include .eml reference in docs commit d9796e5003b9a5bba80f4f1167d07524edb6aa3a Author: phail Date: Sun Nov 20 20:24:36 2022 +0100 change order of elements in parsed Texts commit 3599bb52c05a05132bedf8e641dbd2bcb1ef3410 Author: phail Date: Sun Nov 20 20:12:41 2022 +0100 minor test improvements commit af8a6c3764659efa285b24ede4759aeb99eb6bcb Author: phail Date: Sun Nov 20 19:53:57 2022 +0100 fix filenames commit 6d37ebf79ea655197239982d19193c17dd534b46 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 20 09:15:06 2022 -0800 Fixes one more place which used manual size formatting commit f6a70b85f4cff8d490884a2a11ba45f44c286a98 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 20 09:13:08 2022 -0800 Use Django templating engine commit 538a4219bd951a03c403133087954ac64d4b53a2 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 20 09:10:44 2022 -0800 Fixes missing return commit 85c41b79be2033bdec5226c9687a153d7f4edc06 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun Nov 20 08:02:06 2022 -0800 Adds the new packages without updating other dependencies commit 25d014d8ef8a8dcc7f9cef0ae446eb1418ef0754 Merge: 9ec89762 27f7f0a9 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sun Nov 20 07:48:55 2022 -0800 Merge branch 'beta' into l10n_dev commit 9b01aa9202ccd5ac361ab8b23ff006dcf54aa1ea Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Mon Nov 14 15:47:22 2022 -0800 Fixes the link for flake8 to the new (?) GitHub repo commit df101f5e7a9eb97521d752e9755806a510e12d89 Author: phail Date: Sun Nov 20 16:09:46 2022 +0100 split handle_message function commit 1fa735eb23afe98d156b5ba6bf7560cc65397202 Author: phail Date: Sun Nov 20 15:44:43 2022 +0100 use imagehash instead of bitwise hashing commit ebe21a01140aa5d492c34fc88be63cdfcc57b025 Author: phail Date: Sun Nov 20 14:22:30 2022 +0100 eml parsing requires tika commit d132eba1431fd2c8a9dd57904cb019c26dbcc2e2 Author: phail Date: Sun Nov 20 12:48:03 2022 +0100 optimize regex commit 073c3c8fed873e96a674d227f67ec96e169fbc1d Author: phail Date: Sun Nov 20 12:36:49 2022 +0100 use html.escape instead of some self build functions commit e3c1bde79334940bb70d8ed5235de85bbafc15ca Author: phail Date: Sun Nov 20 12:06:35 2022 +0100 remove log mocking, replace pytest raises, use humanfriendly commit 27f7f0a9411e85710824037d63f0e961c5a1fb4a Merge: 9f5fd6c3 914661fd Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Nov 17 14:31:46 2022 -0800 Merge pull request #1998 from paperless-ngx/fix/1993-date-overflow Bugfix: Don't allow exceptions during date parsing to fail consume commit 9f5fd6c3ba93f08d1982c33e8c861bf1164272d0 Merge: 0ae82005 3dfeee93 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Nov 17 14:30:23 2022 -0800 Merge pull request #1967 from paperless-ngx/feature-scripts-output Feature: Capture stdout & stderr of the pre/post consume scripts commit 914661fdbb7adfd62481013a0bc759c920c1289d Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Thu Nov 17 13:37:37 2022 -0800 Don't allow an exception when trying to parse a date cause complete failure commit 0ae8200593e6c92f92004c2bf13f1e19d930775e Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Mon Nov 14 15:47:22 2022 -0800 Fixes the link for flake8 to the new (?) GitHub repo commit b68906b14ed89832705397b6822cf4001de87626 Author: phail Date: Sun Nov 13 22:49:52 2022 +0100 merge pipfile commit 681eecc46ee042ef54f4f27b92df12685576d153 Merge: 1578e8de d4712234 Author: phail Date: Sun Nov 13 22:43:55 2022 +0100 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit 1578e8de2dab940849975b4664b329000568edc3 Author: phail Date: Sun Nov 13 22:33:26 2022 +0100 fix live tests commit 023c931401db7236d2d1f10def76c1855f465917 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sun Nov 13 07:11:45 2022 -0800 Fix top search not working due to missing button type commit 9ec89762a35e19e7415374e9e24c20b2d16235ac Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Nov 12 09:31:54 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit fa47595ac8b5e411bf68b72dc98f2bfb335ae6d9 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Nov 12 08:58:01 2022 -0800 remove ar_SA [ci skip] commit 79f5019b40dd15effe66ef94a9ca1854908e9937 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Sat Nov 12 08:53:52 2022 -0800 New Crowdin updates (#1971) * New translations messages.xlf (Serbian (Latin)) [ci skip] * New translations messages.xlf (Serbian (Latin)) [ci skip] * New translations messages.xlf (Italian) [ci skip] * New translations django.po (Italian) [ci skip] * New translations django.po (Serbian (Latin)) [ci skip] * New translations messages.xlf (Russian) [ci skip] * New translations messages.xlf (Polish) [ci skip] * New translations messages.xlf (Serbian (Latin)) [ci skip] * New translations messages.xlf (Luxembourgish) [ci skip] * New translations messages.xlf (Croatian) [ci skip] * New translations messages.xlf (Portuguese, Brazilian) [ci skip] * New translations messages.xlf (Chinese Simplified) [ci skip] * New translations messages.xlf (Turkish) [ci skip] * New translations messages.xlf (Swedish) [ci skip] * New translations messages.xlf (Slovenian) [ci skip] * New translations messages.xlf (Portuguese) [ci skip] * New translations messages.xlf (Norwegian) [ci skip] * New translations messages.xlf (German) [ci skip] * New translations messages.xlf (Dutch) [ci skip] * New translations messages.xlf (Italian) [ci skip] * New translations messages.xlf (Hebrew) [ci skip] * New translations messages.xlf (Finnish) [ci skip] * New translations messages.xlf (Danish) [ci skip] * New translations messages.xlf (Czech) [ci skip] * New translations messages.xlf (Belarusian) [ci skip] * New translations messages.xlf (Spanish) [ci skip] * New translations messages.xlf (French) [ci skip] * New translations messages.xlf (Romanian) [ci skip] * New translations messages.xlf (Arabic) [ci skip] * Remove ar-SA * remote ar other than ar-ar Co-authored-by: Michael Shamoon <4887959+shamoon@users.noreply.github.com> commit 756ce2f9d81a9a281e4b219999f0a35de9c536d1 Merge: 50a211f3 d4712234 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Nov 12 08:33:43 2022 -0800 Merge branch 'dev' into beta commit d47122340a20ab429187b4bdbc74a1172da0b1dc Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat Nov 12 08:31:25 2022 -0800 Add translation strings for welcome tour buttons commit b01cbc9aa08a51a63b1719e71335d140ce73a432 Author: phail Date: Sat Nov 12 15:48:30 2022 +0100 add conditions to unittests commit 3dfeee9332f4436467056178d7ddc3ff3a2aa8a8 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Fri Nov 11 10:09:56 2022 -0800 Don't do decoding work if not needed commit 057f6016cc92f6d21b04b9a16dc6f0b255c8b401 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Fri Nov 11 08:58:49 2022 -0800 Adds further testing to cover scripts with non-zero exit codes commit c4965580deebe97b40bfddaa9e0301d0ba108078 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Thu Nov 10 17:40:36 2022 -0800 Fixes stderr appearing to have content when it doesn't commit 9a47963fd5aa54c5bf463110603a19527a057ca3 Author: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Wed Nov 9 20:11:36 2022 -0800 Captures the stdout and stderr of the pre/post scripts into the log commit 50a211f36767a3aee9f679c77ba81f41cc0dea07 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Thu Nov 10 17:25:39 2022 -0800 Fixes an issue with the install of languages and read-only variable commit 5f278d7fbbe1cf690a8215d59339b9cac2b7422c Merge: e5106bdc a17d2519 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed Nov 9 21:37:29 2022 -0800 Merge pull request #1956 from paperless-ngx/l10n_dev New Crowdin updates commit a17d251913ac65f852aa8e80b63a306358956533 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:37 2022 -0800 New translations django.po (Serbian (Latin)) [ci skip] commit 1cbf08865698a05301d88275bbad485ea325a92a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:36 2022 -0800 New translations messages.xlf (Serbian (Latin)) [ci skip] commit d3254d6bcfffc0e3abe95b86a9b1912c6616b77e Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:35 2022 -0800 New translations messages.xlf (Luxembourgish) [ci skip] commit 1543729c7be2684d47a1e7a28e8b7647f01801de Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:34 2022 -0800 New translations messages.xlf (Croatian) [ci skip] commit ef2a96c34b9de59bb0cd7f9e98b721ce3848a076 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:32 2022 -0800 New translations messages.xlf (Portuguese, Brazilian) [ci skip] commit 656b1e150ffd10527b0139ed3ea554ca6435d8c5 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:31 2022 -0800 New translations messages.xlf (Chinese Simplified) [ci skip] commit e0f61003cfeb46543bd68ccaa067977078149c35 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:30 2022 -0800 New translations messages.xlf (Turkish) [ci skip] commit 1ca98678cd592670a3366fcda0dd2fd06dda950f Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:28 2022 -0800 New translations messages.xlf (Swedish) [ci skip] commit 9919cc19567ea753552e09626795c07c45b9a737 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:27 2022 -0800 New translations messages.xlf (Slovenian) [ci skip] commit d2096e3c0593af1149f9a5395536cf309f450826 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:26 2022 -0800 New translations messages.xlf (Portuguese) [ci skip] commit 5f2b508b7a3800936fb2fbbb403a641d7550c97c Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:24 2022 -0800 New translations messages.xlf (Polish) [ci skip] commit 752d4f424900a72c92306b0151b474672b22c99d Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:23 2022 -0800 New translations django.po (German) [ci skip] commit 72e7d5150e724b63fd3ae6f34fb443375a939e04 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:22 2022 -0800 New translations messages.xlf (Norwegian) [ci skip] commit 42a9e05a7fe1fd16a471fe006f2185b6d34ed658 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:21 2022 -0800 New translations messages.xlf (Italian) [ci skip] commit b4add2ed55b346fdf3bb00dc5e4ea88457e9fbdc Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:19 2022 -0800 New translations messages.xlf (Hebrew) [ci skip] commit ed7d9295bd291626ef52a0f3f498884da04d4d3a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:18 2022 -0800 New translations messages.xlf (Finnish) [ci skip] commit 5b7b1b2349db8daf23b3f89af865109c8fde99cc Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:16 2022 -0800 New translations messages.xlf (Danish) [ci skip] commit d5c930acc955e4ebbb5cdc6e1f35da32c99fc729 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:15 2022 -0800 New translations messages.xlf (Czech) [ci skip] commit 4c93d6d7e616c4bdb8cc205d50b918433626fc07 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:14 2022 -0800 New translations messages.xlf (Belarusian) [ci skip] commit 066f3264fbf760158c2a8d65645a86666b9f2811 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:12 2022 -0800 New translations messages.xlf (Spanish) [ci skip] commit 88a803f94950523b62cf7ea412642363fbaeb7b5 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:11 2022 -0800 New translations messages.xlf (French) [ci skip] commit e69615dc0665db8897004050ee7476df11cccbde Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:10 2022 -0800 New translations messages.xlf (Romanian) [ci skip] commit a1e0840e2486faacd3dcc492def43106922ca18d Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:08 2022 -0800 New translations messages.xlf (Dutch) [ci skip] commit d814353e830bdd442cd381fd546ed02103ce31a8 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:07 2022 -0800 New translations messages.xlf (German) [ci skip] commit 06d7845ecae8cba3bf4219ab8bf9194f6e6c3a3a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:04 2022 -0800 New translations django.po (Dutch) [ci skip] commit ae8682c7a53d224f672aa6e2444a2b32c3e428d8 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:03 2022 -0800 New translations django.po (Romanian) [ci skip] commit c9c0b3d43031b01b38ace9ee345f97c9835964c6 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:02 2022 -0800 New translations django.po (Luxembourgish) [ci skip] commit cc46fc7e4ba09f785abb39ec9c3ef4c9109a6707 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:01 2022 -0800 New translations django.po (Croatian) [ci skip] commit d1b1ba21cd3b0b7038e62936818352c77f67a12b Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:12:00 2022 -0800 New translations django.po (Portuguese, Brazilian) [ci skip] commit a009417a996401622db2a336e94312fe7480364c Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:59 2022 -0800 New translations django.po (Chinese Simplified) [ci skip] commit 775da720ec5dde3562d2b01c536e0ff4ffc4351b Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:58 2022 -0800 New translations django.po (Turkish) [ci skip] commit aeae6ea0d349f3bbf4ebbb9b7b14652537b1a48c Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:57 2022 -0800 New translations django.po (Swedish) [ci skip] commit 0ae46d2269c503327071c3667946aa060c433ad8 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:56 2022 -0800 New translations django.po (Slovenian) [ci skip] commit 0e7f1ec0dee2a2b3513e901f3489d1f3bd564ab7 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:55 2022 -0800 New translations django.po (Russian) [ci skip] commit 13cd55b96fac9bd5c1b61e93fc19d4556e6b0b5a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:53 2022 -0800 New translations django.po (Portuguese) [ci skip] commit 9139e807ecb7115663e1e65ac3b855c58c57ab6a Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:52 2022 -0800 New translations messages.xlf (Arabic) [ci skip] commit 53616f6625663d97437d781cdede1281dac5c062 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:51 2022 -0800 New translations django.po (Polish) [ci skip] commit 526fdf11535f87d67c88e5b02d1e9fd89e451fb2 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:50 2022 -0800 New translations django.po (Italian) [ci skip] commit fc4aceb0eea83800aff0c0f3bde9711e1393b79e Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:49 2022 -0800 New translations django.po (Hebrew) [ci skip] commit 3d8421b718e997b8b1e4913f1279847242817d70 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:48 2022 -0800 New translations django.po (Finnish) [ci skip] commit 6cebceda15ee35410ddb2bfbd50415cbafb4a466 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:47 2022 -0800 New translations django.po (Danish) [ci skip] commit e1fd6bda19fff639daa17b7273616f714af37f9f Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:46 2022 -0800 New translations django.po (Czech) [ci skip] commit fd34414b1725f52b9834dc6d633f4cf01666f819 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:45 2022 -0800 New translations django.po (Belarusian) [ci skip] commit 3ce1886a545db3d46356a65670776bc32bd6cc3c Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:44 2022 -0800 New translations django.po (Arabic) [ci skip] commit 8ed43779a878fb04ba47d03722ea206bc9d4340c Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:43 2022 -0800 New translations django.po (Spanish) [ci skip] commit a7949b3e229f3c224684ee49f8fdcafa7f7cd95f Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:42 2022 -0800 New translations django.po (French) [ci skip] commit 19c293c3e6d80e386699aef33c0c96de07e4300c Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:41 2022 -0800 New translations django.po (Norwegian) [ci skip] commit ccb1ec4ff5fec68579d3d4e173ee5fc4509d3a23 Author: Paperless-ngx Translation Bot [bot] <99855517+paperless-l10n@users.noreply.github.com> Date: Wed Nov 9 15:11:40 2022 -0800 New translations messages.xlf (Russian) [ci skip] commit e5106bdca0811d313a6b7894a27aa301a7b3cf90 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Wed Nov 9 14:00:09 2022 -0800 Updates the version strings to 1.10.0 commit ba1366f49a01c7e2723e1ae4e05650e9ddae6744 Merge: 34a0111f f3b3db30 Author: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Wed Nov 9 13:51:10 2022 -0800 Merge branch 'dev' into beta commit acd383241777e16e923ecceece9f2b669adb1ef3 Author: phail Date: Thu Nov 3 21:08:15 2022 +0100 merge Pipfile.lock commit 82b2ba3cc2a3fb7a692f54d6c05d2395350b136f Merge: 3de6e0bc 7e3e0a0f Author: phail Date: Thu Nov 3 21:00:01 2022 +0100 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit 3de6e0bcf1b6e0e7afe578e37fd67f5b455c1987 Author: phail Date: Thu Nov 3 00:58:36 2022 +0100 put parser into setup make test using convert optional Gotenberg live testing commit 34a0111ff5ca7dd096d69d0b4a11b97dd6121ea1 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Oct 31 13:06:17 2022 -0700 update logs section commit b511b084d08e6e33964649f6eb1d2fadcc7cc844 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sun Oct 30 06:48:41 2022 -0700 Update matrix url [ci skip] commit 6df73ae940420eed2b1f5c300b90992d0becb013 Author: phail Date: Sat Oct 29 23:20:35 2022 +0200 gotenberg with modified cmd commit 4a24ba51c5dadf5a99e060c6147f00210c954004 Merge: 87472b31 d5fb98b7 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Oct 28 22:22:08 2022 -0700 Merge pull request #1876 from astubenbord/main Added new application to list of affiliated projects commit d5fb98b7c43e607bc89602d680772d5278133a55 Author: Anton Stubenbord <79228196+astubenbord@users.noreply.github.com> Date: Fri Oct 28 11:07:42 2022 +0200 Added new application to list of affiliated projects commit 2204090151dbb34f57af8482366db1b3a4153ad8 Author: phail Date: Thu Oct 27 23:53:47 2022 +0200 fix string commit 3c81a7468b47cdf5a2df0826429df99ab21f769b Author: phail Date: Thu Oct 27 23:41:29 2022 +0200 replace thumbnail creation with mock commit 5ef86f9489a43204b7ff840172a80bd0783ac260 Merge: 90cb0836 9b82ab95 Author: phail Date: Thu Oct 27 23:12:51 2022 +0200 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit 90cb0836bb5d5f06b205290c2431efa7527b7c72 Author: phail Date: Thu Oct 27 23:11:41 2022 +0200 Downgrade pdf validation to text only commit ef1d4264b53d4eea2df6897c98cc31d883e35073 Author: phail Date: Thu Oct 27 00:27:15 2022 +0200 improve test coverage a little commit e1fa59122dbf3224c5c5100dccee369c43a7fb8a Merge: 5bf26369 3357fa19 Author: phail Date: Wed Oct 26 20:59:49 2022 +0200 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit 5bf26369e2b215e4418c49180c8393fc09365eea Author: phail Date: Tue Oct 25 21:17:40 2022 +0200 remove erroring paramerter commit 36239ba09f0ffc6e30cb5014f26e3edc0f7dd862 Author: phail Date: Mon Oct 24 22:15:33 2022 +0200 rename help text commit 318c1d2fbd4eb9cd000ccb39dcce5eb060647eee Merge: e7c40fc3 f8ce6285 Author: phail Date: Mon Oct 24 21:12:35 2022 +0200 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit e7c40fc3dc645d4fbe9665d82595aff71060b071 Author: phail Date: Sun Oct 23 22:02:11 2022 +0200 Update Pipfile commit 0da0b1c062138ec0bc8117fcfec5cd05074ac771 Author: phail Date: Sun Oct 23 21:39:15 2022 +0200 update variable names commit 08988e11f81c4db9411109cd5f48d365c9c30c11 Merge: 30372b0e 8be6c707 Author: phail Date: Sun Oct 23 20:37:22 2022 +0200 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit 30372b0e8564ab7de6986e8acd132a3b6df0ceb4 Author: phail Date: Sun Oct 23 17:18:10 2022 +0200 add tests for mail_to_html and generate_pdf_from_mail commit 567e89d1c7a8fea4f66b717d3ba4cb9680fba0da Author: phail Date: Sat Oct 22 02:25:23 2022 +0200 test for broken eml, add test_generate_pdf commit f1f5227ccdbb75fff2f6af8ed1992e384939bcc5 Author: phail Date: Sat Oct 22 00:44:32 2022 +0200 add unittest for external images commit 09b5bd17f2123db0679b10abd8c819b2c2a903ce Author: phail Date: Wed Oct 19 23:19:33 2022 +0200 add unittest for generate_pdf_from_html commit e384bd78c5eeb97fce8652dde24a44e71c040d39 Author: phail Date: Tue Oct 18 23:48:07 2022 +0200 add unittest for transform_inline_html commit fda844f64cce6247f484dd8d14038ea36db9f934 Author: phail Date: Sat Oct 15 15:41:43 2022 +0200 add unittest for parse commit daf90399bddd5cf85e25204a50860995eb55efaf Author: phail Date: Sat Oct 15 13:13:29 2022 +0200 Add unitest for tika_parse() commit 3d37e49c1a41f117518d73165311710d79045d8f Author: phail Date: Fri Oct 14 15:43:43 2022 +0200 add 2 more tests commit 261c6fb9904e5365ca5c8f61a944ffff1c448d5c Author: phail Date: Thu Oct 13 01:03:09 2022 +0200 add unittest for get_thumbnail commit 87472b31d27be1fff304377ec3260268f3ecc44d Merge: 430c5c3b 1024d7e6 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Oct 11 19:59:46 2022 -0700 Merge pull request #1780 from paperless-ngx/fix/issue-1647 Documentation: Add note re MS exchange servers commit 1024d7e6e23c1fd64e29959faa97c69af53caf80 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Oct 11 15:12:22 2022 -0700 Add note re MS exchange servers commit 430c5c3b87cab852bb556fca83dc737fc30f7c23 Merge: 0b5c6d35 b7c33550 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri Oct 7 23:45:51 2022 -0700 Merge pull request #1761 from paperless-ngx/docs/lsio-tweak Documentation: Tweak LinuxServer commit b7c335507ff9a38c316f1c4a727a9b2128f05069 Author: Trenton Holmes Date: Thu Oct 6 18:24:25 2022 -0700 Fixes the LSIO migration setting for the media root commit 0b5c6d3532d364258f5c93ddfdcc5e8054ba0fbb Merge: fdac108c 5fd39472 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu Oct 6 13:22:58 2022 -0700 Merge pull request #1731 from paperless-ngx/fix/1624 Documentation: Adds troubleshooting note about Kubernetes and ports commit fdac108cab86d3d9504994f0454a7611576c45a9 Merge: 5639659b 821c14fb Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon Oct 3 17:07:06 2022 -0700 Merge pull request #1733 from paperless-ngx/docs-lsio-migrate Documentation: LinuxServer.io Migration commit 821c14fbce0e776e26317366c7a4e1ed0bc449d0 Author: Trenton H Date: Mon Oct 3 11:14:18 2022 -0700 Corrects how the link to example compose files looks commit 8c03d9c63837a47f328711d33d154a33aae8685b Author: Trenton H Date: Mon Oct 3 11:11:51 2022 -0700 Corrects a re-numbered step commit 174a609449d4ed7d9210175d98f33407ac2f0533 Author: Trenton H Date: Mon Oct 3 10:16:53 2022 -0700 Adds a few steps for migration from the LinuxServer.io image commit 5fd394726ee1718d762c71efb4203f0e66c1df54 Author: Trenton H Date: Mon Oct 3 09:01:07 2022 -0700 Adds troubleshooting note for Kubernetes about needing to set the port again commit 5639659b6384fc675569fbec044bc2757a6696f5 Merge: 807b7130 7ba9cdbe Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed Sep 28 09:48:20 2022 -0700 Merge pull request #1683 from paperless-ngx/fix/issue-1660 Mariadb compose files should use `PAPERLESS_DBPASS` commit 7ba9cdbe23365082a958856f5f52bae2908b3e14 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed Sep 28 09:07:30 2022 -0700 Mariadb compose files should use `PAPERLESS_DBPASS` commit 807b7130e5bb422d1ae418d65a9203076db262cb Merge: 9d117ee1 e2d593c0 Author: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Sep 27 16:50:23 2022 -0700 Merge pull request #1671 from paperless-ngx/v1.9.2-changelog [Documentation] Add v1.9.2 changelog commit e2d593c023ea12853e777d70d01db201db7e38e4 Author: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue Sep 27 10:04:41 2022 -0700 Fix formatting, add note about 1.9.1 version string commit 74559631244a906fe38ba050fe391d9efeb1f343 Author: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue Sep 27 17:01:37 2022 +0000 Changelog - GHA commit cdd2b99b6b29cfb1fd8e9c3ceeb367d3237fd665 Merge: d0a0ae91 72ce4405 Author: phail Date: Mon Jul 11 23:58:21 2022 +0200 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit d0a0ae91c416cad9ccdb01fc9ed93e6f8c4214fc Merge: c04b9fd7 feaf2da8 Author: phail Date: Fri May 20 19:29:52 2022 +0200 Merge branch 'dev' into feature-consume-eml commit c04b9fd7f6a63c2889c59e0168956d89369c4876 Author: phail Date: Thu May 19 22:51:17 2022 +0200 switch to From: Header instead of date to compensate for older libmagic versions commit 6809b15ce13c9d07d24a8308ed97e3b42cc5eae4 Author: phail Date: Sat May 14 16:47:12 2022 +0200 workaround for wrong mime detection of .eml files commit c317eca1ca40cf94e83873112c7dede513574714 Author: phail Date: Thu May 5 00:20:32 2022 +0200 add attachment size to pdf commit 466afa820352a0da59fc60b3d0e08fcc037ac11b Author: phail Date: Wed May 4 23:42:59 2022 +0200 fix consumption of mails without html split pdf generation functions commit c2e3dc76d94d02d86d9005d08962e9e4acff3b0c Author: phail Date: Tue May 3 23:21:33 2022 +0200 add parsing of inline attachments remove insecure chromium option fix html parsing commit 5a899664f804eb44055221b02a561ad632638158 Author: phail Date: Tue May 3 18:02:08 2022 +0200 remove .eml parser from tika commit 990e905a04c78d356b0c5c3e8f53a15151af2d5d Merge: 6b7155a8 98ebb095 Author: phail Date: Tue May 3 17:42:56 2022 +0200 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit 6b7155a8498241f707b73d5659168ac687d7d4a1 Author: phail Date: Sat Apr 30 17:33:12 2022 +0200 merge migrations commit 47851ddd3f54fcddb34af370e002e927eaa431b8 Merge: 47189643 0f1e3164 Author: phail Date: Fri Apr 29 23:52:56 2022 +0200 Merge remote-tracking branch 'paperless/dev' into feature-consume-eml commit 47189643ff07059e9c9c256f725bdf837c481811 Author: phail Date: Fri Apr 29 22:58:11 2022 +0200 add eml parser to paperless_mail commit c1efe11cf3908aa6920e795a785451fd11c2eb71 Author: phail Date: Wed Apr 27 23:32:10 2022 +0200 improve pdf generation commit 0e40ef5f352ca3e6ffe5b76374481f2a888e24dd Author: phail Date: Wed Apr 27 19:52:59 2022 +0200 add css for pdf generation commit c8081595c4450780eade4921a81d0b1bd08105cc Author: phail Date: Tue Apr 26 23:25:48 2022 +0200 improve pdf generation commit a2b5b3b2530daf7e88600d88803eb4ee43ab8dad Author: phail Date: Tue Apr 26 23:12:36 2022 +0200 moved files commit 790bcf05ed7f478dd497a8f4fcb47c10063a7859 Author: phail Date: Mon Apr 25 20:55:00 2022 +0200 add prototype archive pdf commit d8d2d53c59c4902f94b9ac76f16a370662b9086e Author: phail Date: Tue Apr 19 20:14:31 2022 +0200 fix Mail actions mixup commit 027897ff0309423f524626b894981298a3606c8b Author: phail Date: Tue Apr 19 00:39:00 2022 +0200 work in progress Mail parsing commit cca576f5182fddcdeb132832fdf3fae0edfe4bfd Author: phail Date: Fri Apr 15 14:40:02 2022 +0200 add feature to consume imap mail als .eml commit 5fcf1b5434f42a55ebe4dd083d3021f27234d0cf Author: phail Date: Thu Apr 14 00:19:30 2022 +0200 remove uneeded print and fix merge fail commit 942b5aa9df53a1e0362ad4a0f65b64863829ac64 Merge: c05b39a0 cc936160 Author: phail Date: Wed Apr 13 23:55:38 2022 +0200 Merge branch 'dev' into fix-mail-starttls commit c05b39a05640fa00d43de9a8c1f96f737c3a2f45 Author: phail Date: Wed Apr 13 23:37:21 2022 +0200 fix unittest commit 3c8196527f73fdcbdd8da9fdc5d199184b78a254 Author: phail Date: Sat Apr 9 13:07:14 2022 +0200 adapt to starttls interface change in imap_tools pin imap-tools version to avoid breaking changes improve mail log Update settings.component.ts Update settings.component.ts --- .github/ISSUE_TEMPLATE/bug-report.yml | 14 +- .github/PULL_REQUEST_TEMPLATE.md | 4 +- .github/workflows/ci.yml | 57 +- .github/workflows/release-chart.yml | 31 + .gitignore | 4 +- .pre-commit-config.yaml | 5 +- .readthedocs.yml | 16 - CONTRIBUTING.md | 4 +- Dockerfile | 43 +- Pipfile | 7 +- Pipfile.lock | 299 +- README.md | 22 +- charts/paperless-ngx/.helmignore | 26 + charts/paperless-ngx/Chart.yaml | 35 + charts/paperless-ngx/LICENSE | 201 + charts/paperless-ngx/README.md | 50 + charts/paperless-ngx/README_CONFIG.md.gotmpl | 8 + charts/paperless-ngx/ci/ct-values.yaml | 26 + charts/paperless-ngx/templates/NOTES.txt | 4 + charts/paperless-ngx/templates/common.yaml | 11 + charts/paperless-ngx/values.yaml | 107 + docker/compose/docker-compose.ci-test.yml | 25 + .../compose/docker-compose.mariadb-tika.yml | 9 +- docker/compose/docker-compose.mariadb.yml | 4 +- .../compose/docker-compose.postgres-tika.yml | 6 +- docker/compose/docker-compose.sqlite-tika.yml | 6 +- docker/docker-entrypoint.sh | 47 +- docker/docker-prepare.sh | 43 - docs/Makefile | 181 - docs/_static/css/custom.css | 597 - docs/_static/js/darkmode.js | 47 - .../_static/screenshots/mail-rules-edited.png | Bin 98619 -> 0 bytes docs/_templates/layout.html | 13 - docs/administration.md | 502 + docs/administration.rst | 523 - docs/advanced_usage.md | 468 + docs/advanced_usage.rst | 419 - docs/api.md | 318 + docs/api.rst | 303 - docs/{_static => assets}/.keep | 0 docs/assets/extra.css | 36 + docs/assets/favicon.png | Bin 0 -> 768 bytes docs/assets/logo.svg | 12 + docs/assets/logo_full_black.svg | 68 + docs/assets/logo_full_white.svg | 69 + .../recommended_workflow.png | Bin .../screenshots/bulk-edit.png | Bin .../screenshots/correspondents.png | Bin .../screenshots/dashboard.png | Bin .../screenshots/documents-filter.png | Bin .../screenshots/documents-largecards.png | Bin .../screenshots/documents-smallcards-dark.png | Bin .../screenshots/documents-smallcards.png | Bin .../screenshots/documents-table.png | Bin .../screenshots/documents-wchrome-dark.png | Bin .../screenshots/documents-wchrome.png | Bin .../screenshots/editing.png | Bin docs/{_static => assets}/screenshots/logs.png | Bin docs/assets/screenshots/mail-rules-edited.png | Bin 0 -> 77537 bytes .../screenshots/mobile.png | Bin .../screenshots/new-tag.png | Bin .../screenshots/search-preview.png | Bin .../screenshots/search-results.png | Bin docs/changelog.md | 431 +- docs/conf.py | 337 - docs/configuration.md | 1036 ++ docs/configuration.rst | 925 -- docs/development.md | 469 + docs/extending.rst | 431 - docs/faq.md | 125 + docs/faq.rst | 117 - docs/index.md | 138 + docs/index.rst | 75 - docs/requirements.txt | 1 - docs/scanners.rst | 8 - docs/screenshots.rst | 63 - docs/setup.md | 856 ++ docs/setup.rst | 846 -- docs/troubleshooting.md | 334 + docs/troubleshooting.rst | 319 - docs/usage.md | 483 + docs/usage_overview.rst | 420 - install-paperless-ngx.sh | 3 + mkdocs.yml | 62 + paperless.conf.example | 2 +- scripts/start_services.sh | 2 +- src-ui/cypress/e2e/settings/settings.cy.ts | 17 +- src-ui/cypress/e2e/tasks/tasks.cy.ts | 33 + .../fixtures/mail_accounts/mail_accounts.json | 27 + .../fixtures/mail_rules/mail_rules.json | 29 + .../fixtures/saved_views/savedviews.json | 45 +- src-ui/cypress/fixtures/tasks/tasks.json | 248 +- src-ui/messages.xlf | 1006 +- src-ui/package-lock.json | 2907 ++-- src-ui/package.json | 10 +- src-ui/src/app/app-routing.module.ts | 6 + src-ui/src/app/app.component.ts | 38 +- src-ui/src/app/app.module.ts | 6 + .../app-frame/app-frame.component.html | 11 +- .../app-frame/app-frame.component.ts | 18 +- .../edit-dialog/edit-dialog.component.ts | 12 +- .../mail-account-edit-dialog.component.html | 26 + .../mail-account-edit-dialog.component.scss | 0 .../mail-account-edit-dialog.component.ts | 50 + .../mail-rule-edit-dialog.component.html | 39 + .../mail-rule-edit-dialog.component.scss | 0 .../mail-rule-edit-dialog.component.ts | 180 + .../storage-path-edit-dialog.component.html | 2 +- .../storage-path-edit-dialog.component.ts | 2 +- .../common/input/number/number.component.html | 2 +- .../common/input/number/number.component.ts | 5 +- .../input/password/password.component.html | 8 + .../input/password/password.component.scss | 0 .../input/password/password.component.ts | 21 + .../common/input/tags/tags.component.html | 4 +- .../common/input/tags/tags.component.ts | 3 + .../welcome-widget.component.html | 2 +- .../document-detail.component.ts | 2 +- .../management-list.component.ts | 32 +- .../manage/settings/settings.component.html | 93 +- .../manage/settings/settings.component.ts | 293 +- .../manage/tasks/tasks.component.html | 6 +- src-ui/src/app/data/paperless-mail-account.ts | 23 + src-ui/src/app/data/paperless-mail-rule.ts | 60 + src-ui/src/app/data/paperless-task.ts | 4 +- src-ui/src/app/guards/dirty-form.guard.ts | 1 - .../app/services/rest/mail-account.service.ts | 51 + .../app/services/rest/mail-rule.service.ts | 49 + src-ui/src/environments/environment.prod.ts | 2 +- src-ui/src/locale/messages.ar_SA.xlf | 4375 ++++++ src-ui/src/locale/messages.be_BY.xlf | 306 +- src-ui/src/locale/messages.cs_CZ.xlf | 306 +- src-ui/src/locale/messages.da_DK.xlf | 306 +- src-ui/src/locale/messages.de_DE.xlf | 316 +- src-ui/src/locale/messages.es_ES.xlf | 306 +- src-ui/src/locale/messages.fi_FI.xlf | 306 +- src-ui/src/locale/messages.fr_FR.xlf | 306 +- src-ui/src/locale/messages.he_IL.xlf | 306 +- src-ui/src/locale/messages.hr_HR.xlf | 306 +- src-ui/src/locale/messages.it_IT.xlf | 318 +- src-ui/src/locale/messages.lb_LU.xlf | 342 +- src-ui/src/locale/messages.nl_NL.xlf | 306 +- src-ui/src/locale/messages.no_NO.xlf | 306 +- src-ui/src/locale/messages.pl_PL.xlf | 306 +- src-ui/src/locale/messages.pt_BR.xlf | 306 +- src-ui/src/locale/messages.pt_PT.xlf | 306 +- src-ui/src/locale/messages.ro_RO.xlf | 306 +- src-ui/src/locale/messages.ru_RU.xlf | 306 +- src-ui/src/locale/messages.sl_SI.xlf | 306 +- src-ui/src/locale/messages.sr_CS.xlf | 346 +- src-ui/src/locale/messages.sv_SE.xlf | 306 +- src-ui/src/locale/messages.tr_TR.xlf | 306 +- src-ui/src/locale/messages.zh_CN.xlf | 306 +- src-ui/src/styles.scss | 10 +- src/documents/consumer.py | 76 +- src/documents/parsers.py | 2 +- src/documents/signals/handlers.py | 7 +- src/documents/tasks.py | 9 + src/documents/templates/index.html | 2 +- src/documents/tests/test_consumer.py | 117 +- src/locale/ar_BH/LC_MESSAGES/django.po | 698 - src/locale/ar_EG/LC_MESSAGES/django.po | 698 - src/locale/ar_YE/LC_MESSAGES/django.po | 698 - src/locale/be_BY/LC_MESSAGES/django.po | 348 +- src/locale/cs_CZ/LC_MESSAGES/django.po | 348 +- src/locale/da_DK/LC_MESSAGES/django.po | 346 +- src/locale/de_DE/LC_MESSAGES/django.po | 348 +- src/locale/es_ES/LC_MESSAGES/django.po | 346 +- src/locale/fi_FI/LC_MESSAGES/django.po | 348 +- src/locale/fr_FR/LC_MESSAGES/django.po | 348 +- src/locale/he_IL/LC_MESSAGES/django.po | 346 +- src/locale/hr_HR/LC_MESSAGES/django.po | 348 +- src/locale/it_IT/LC_MESSAGES/django.po | 348 +- src/locale/lb_LU/LC_MESSAGES/django.po | 346 +- src/locale/nl_NL/LC_MESSAGES/django.po | 348 +- src/locale/no_NO/LC_MESSAGES/django.po | 348 +- src/locale/pl_PL/LC_MESSAGES/django.po | 348 +- src/locale/pt_BR/LC_MESSAGES/django.po | 346 +- src/locale/pt_PT/LC_MESSAGES/django.po | 346 +- src/locale/ro_RO/LC_MESSAGES/django.po | 346 +- src/locale/ru_RU/LC_MESSAGES/django.po | 348 +- src/locale/sl_SI/LC_MESSAGES/django.po | 348 +- src/locale/sr_CS/LC_MESSAGES/django.po | 348 +- src/locale/sv_SE/LC_MESSAGES/django.po | 346 +- src/locale/tr_TR/LC_MESSAGES/django.po | 348 +- src/locale/zh_CN/LC_MESSAGES/django.po | 348 +- src/paperless/settings.py | 49 +- src/paperless/tests/test_settings.py | 57 + src/paperless/urls.py | 4 + src/paperless/version.py | 2 +- src/paperless_mail/admin.py | 5 +- src/paperless_mail/apps.py | 9 + src/paperless_mail/mail.py | 104 +- .../0016_mailrule_consumption_scope.py | 32 + src/paperless_mail/models.py | 14 + src/paperless_mail/parsers.py | 333 + src/paperless_mail/serialisers.py | 110 + src/paperless_mail/signals.py | 14 + .../templates/email_msg_template.html | 48 + src/paperless_mail/templates/input.css | 3 + src/paperless_mail/templates/output.css | 706 + .../templates/package-lock.json | 1260 ++ src/paperless_mail/templates/package.json | 5 + .../templates/tailwind.config.js | 7 + src/paperless_mail/tests/samples/broken.eml | 1 + src/paperless_mail/tests/samples/first.pdf | Bin 0 -> 6714 bytes src/paperless_mail/tests/samples/html.eml | 11599 ++++++++++++++++ .../tests/samples/html.eml.html | 45 + src/paperless_mail/tests/samples/html.eml.pdf | Bin 0 -> 23054 bytes .../tests/samples/html.eml.pdf.webp | Bin 0 -> 6098 bytes src/paperless_mail/tests/samples/sample.html | 19 + .../tests/samples/sample.html.pdf | Bin 0 -> 30170 bytes .../tests/samples/sample.html.pdf.webp | Bin 0 -> 2830 bytes src/paperless_mail/tests/samples/sample.png | Bin 0 -> 7057 bytes src/paperless_mail/tests/samples/second.pdf | Bin 0 -> 6723 bytes .../tests/samples/simple_text.eml | 25 + .../tests/samples/simple_text.eml.pdf | Bin 0 -> 22301 bytes .../tests/samples/simple_text.eml.pdf.webp | Bin 0 -> 5340 bytes src/paperless_mail/tests/test_api.py | 429 + src/paperless_mail/tests/test_parsers.py | 688 + src/paperless_mail/tests/test_parsers_live.py | 361 + src/paperless_mail/views.py | 41 + src/paperless_tesseract/checks.py | 12 +- src/paperless_tesseract/parsers.py | 17 +- src/paperless_tesseract/signals.py | 1 + .../tests/samples/document.webp | Bin 0 -> 5794 bytes .../tests/samples/single-page-mixed.pdf | Bin 0 -> 21901 bytes src/paperless_tesseract/tests/test_checks.py | 37 + src/paperless_tesseract/tests/test_parser.py | 81 +- 229 files changed, 39451 insertions(+), 16009 deletions(-) create mode 100644 .github/workflows/release-chart.yml delete mode 100644 .readthedocs.yml create mode 100644 charts/paperless-ngx/.helmignore create mode 100644 charts/paperless-ngx/Chart.yaml create mode 100644 charts/paperless-ngx/LICENSE create mode 100644 charts/paperless-ngx/README.md create mode 100644 charts/paperless-ngx/README_CONFIG.md.gotmpl create mode 100644 charts/paperless-ngx/ci/ct-values.yaml create mode 100644 charts/paperless-ngx/templates/NOTES.txt create mode 100644 charts/paperless-ngx/templates/common.yaml create mode 100644 charts/paperless-ngx/values.yaml create mode 100644 docker/compose/docker-compose.ci-test.yml delete mode 100644 docs/Makefile delete mode 100644 docs/_static/css/custom.css delete mode 100644 docs/_static/js/darkmode.js delete mode 100644 docs/_static/screenshots/mail-rules-edited.png delete mode 100644 docs/_templates/layout.html create mode 100644 docs/administration.md delete mode 100644 docs/administration.rst create mode 100644 docs/advanced_usage.md delete mode 100644 docs/advanced_usage.rst create mode 100644 docs/api.md delete mode 100644 docs/api.rst rename docs/{_static => assets}/.keep (100%) create mode 100644 docs/assets/extra.css create mode 100644 docs/assets/favicon.png create mode 100644 docs/assets/logo.svg create mode 100644 docs/assets/logo_full_black.svg create mode 100644 docs/assets/logo_full_white.svg rename docs/{_static => assets}/recommended_workflow.png (100%) rename docs/{_static => assets}/screenshots/bulk-edit.png (100%) rename docs/{_static => assets}/screenshots/correspondents.png (100%) rename docs/{_static => assets}/screenshots/dashboard.png (100%) rename docs/{_static => assets}/screenshots/documents-filter.png (100%) rename docs/{_static => assets}/screenshots/documents-largecards.png (100%) rename docs/{_static => assets}/screenshots/documents-smallcards-dark.png (100%) rename docs/{_static => assets}/screenshots/documents-smallcards.png (100%) rename docs/{_static => assets}/screenshots/documents-table.png (100%) rename docs/{_static => assets}/screenshots/documents-wchrome-dark.png (100%) rename docs/{_static => assets}/screenshots/documents-wchrome.png (100%) rename docs/{_static => assets}/screenshots/editing.png (100%) rename docs/{_static => assets}/screenshots/logs.png (100%) create mode 100644 docs/assets/screenshots/mail-rules-edited.png rename docs/{_static => assets}/screenshots/mobile.png (100%) rename docs/{_static => assets}/screenshots/new-tag.png (100%) rename docs/{_static => assets}/screenshots/search-preview.png (100%) rename docs/{_static => assets}/screenshots/search-results.png (100%) delete mode 100644 docs/conf.py create mode 100644 docs/configuration.md delete mode 100644 docs/configuration.rst create mode 100644 docs/development.md delete mode 100644 docs/extending.rst create mode 100644 docs/faq.md delete mode 100644 docs/faq.rst create mode 100644 docs/index.md delete mode 100644 docs/index.rst delete mode 100644 docs/requirements.txt delete mode 100644 docs/scanners.rst delete mode 100644 docs/screenshots.rst create mode 100644 docs/setup.md delete mode 100644 docs/setup.rst create mode 100644 docs/troubleshooting.md delete mode 100644 docs/troubleshooting.rst create mode 100644 docs/usage.md delete mode 100644 docs/usage_overview.rst create mode 100644 mkdocs.yml create mode 100644 src-ui/cypress/fixtures/mail_accounts/mail_accounts.json create mode 100644 src-ui/cypress/fixtures/mail_rules/mail_rules.json create mode 100644 src-ui/src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html create mode 100644 src-ui/src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.scss create mode 100644 src-ui/src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts create mode 100644 src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html create mode 100644 src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.scss create mode 100644 src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts create mode 100644 src-ui/src/app/components/common/input/password/password.component.html create mode 100644 src-ui/src/app/components/common/input/password/password.component.scss create mode 100644 src-ui/src/app/components/common/input/password/password.component.ts create mode 100644 src-ui/src/app/data/paperless-mail-account.ts create mode 100644 src-ui/src/app/data/paperless-mail-rule.ts create mode 100644 src-ui/src/app/services/rest/mail-account.service.ts create mode 100644 src-ui/src/app/services/rest/mail-rule.service.ts create mode 100644 src-ui/src/locale/messages.ar_SA.xlf delete mode 100644 src/locale/ar_BH/LC_MESSAGES/django.po delete mode 100644 src/locale/ar_EG/LC_MESSAGES/django.po delete mode 100644 src/locale/ar_YE/LC_MESSAGES/django.po create mode 100644 src/paperless_mail/migrations/0016_mailrule_consumption_scope.py create mode 100644 src/paperless_mail/parsers.py create mode 100644 src/paperless_mail/serialisers.py create mode 100644 src/paperless_mail/signals.py create mode 100644 src/paperless_mail/templates/email_msg_template.html create mode 100644 src/paperless_mail/templates/input.css create mode 100644 src/paperless_mail/templates/output.css create mode 100644 src/paperless_mail/templates/package-lock.json create mode 100644 src/paperless_mail/templates/package.json create mode 100644 src/paperless_mail/templates/tailwind.config.js create mode 100644 src/paperless_mail/tests/samples/broken.eml create mode 100644 src/paperless_mail/tests/samples/first.pdf create mode 100644 src/paperless_mail/tests/samples/html.eml create mode 100644 src/paperless_mail/tests/samples/html.eml.html create mode 100644 src/paperless_mail/tests/samples/html.eml.pdf create mode 100644 src/paperless_mail/tests/samples/html.eml.pdf.webp create mode 100644 src/paperless_mail/tests/samples/sample.html create mode 100644 src/paperless_mail/tests/samples/sample.html.pdf create mode 100644 src/paperless_mail/tests/samples/sample.html.pdf.webp create mode 100644 src/paperless_mail/tests/samples/sample.png create mode 100644 src/paperless_mail/tests/samples/second.pdf create mode 100644 src/paperless_mail/tests/samples/simple_text.eml create mode 100644 src/paperless_mail/tests/samples/simple_text.eml.pdf create mode 100644 src/paperless_mail/tests/samples/simple_text.eml.pdf.webp create mode 100644 src/paperless_mail/tests/test_api.py create mode 100644 src/paperless_mail/tests/test_parsers.py create mode 100644 src/paperless_mail/tests/test_parsers_live.py create mode 100644 src/paperless_mail/views.py create mode 100755 src/paperless_tesseract/tests/samples/document.webp create mode 100644 src/paperless_tesseract/tests/samples/single-page-mixed.pdf diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 1ad06f12e..20de107ef 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -10,8 +10,8 @@ body: Before opening an issue, please double check: - - [The troubleshooting documentation](https://paperless-ngx.readthedocs.io/en/latest/troubleshooting.html). - - [The installation instructions](https://paperless-ngx.readthedocs.io/en/latest/setup.html#installation). + - [The troubleshooting documentation](https://docs.paperless-ngx.com/troubleshooting/). + - [The installation instructions](https://docs.paperless-ngx.com/setup/#installation). - [Existing issues and discussions](https://github.com/paperless-ngx/paperless-ngx/search?q=&type=issues). - Disable any customer container initialization scripts, if using any @@ -42,7 +42,15 @@ body: id: logs attributes: label: Webserver logs - description: If available, post any logs from the web server related to your issue. + description: Logs from the web server related to your issue. + render: bash + validations: + required: true + - type: textarea + id: logs_browser + attributes: + label: Browser logs + description: Logs from the web browser related to your issue, if needed render: bash - type: input id: version diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9e9a9d493..1a652da81 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -26,7 +26,7 @@ NOTE: Please check only one box! - [ ] I have read & agree with the [contributing guidelines](https://github.com/paperless-ngx/paperless-ngx/blob/main/CONTRIBUTING.md). - [ ] If applicable, I have tested my code for new features & regressions on both mobile & desktop devices, using the latest version of major browsers. -- [ ] If applicable, I have checked that all tests pass, see [documentation](https://paperless-ngx.readthedocs.io/en/latest/extending.html#back-end-development). -- [ ] I have run all `pre-commit` hooks, see [documentation](https://paperless-ngx.readthedocs.io/en/latest/extending.html#code-formatting-with-pre-commit-hooks). +- [ ] If applicable, I have checked that all tests pass, see [documentation](https://docs.paperless-ngx.com/development/#back-end-development). +- [ ] I have run all `pre-commit` hooks, see [documentation](https://docs.paperless-ngx.com/development/#code-formatting-with-pre-commit-hooks). - [ ] I have made corresponding changes to the documentation as needed. - [ ] I have checked my modifications for any breaking changes. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ccc93df2..23ace6a3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: name: Set up Python uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: 3.8 cache: "pipenv" cache-dependency-path: 'Pipfile.lock' - @@ -63,14 +63,32 @@ jobs: - name: Make documentation run: | - cd docs/ - pipenv run make html + pipenv run mkdocs build --config-file ./mkdocs.yml - name: Upload artifact uses: actions/upload-artifact@v3 with: name: documentation - path: docs/_build/html/ + path: site/ + + documentation-deploy: + name: "Deploy Documentation" + runs-on: ubuntu-20.04 + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: + - documentation + steps: + - + name: Checkout + uses: actions/checkout@v3 + - + name: Deploy docs + uses: mhausenblas/mkdocs-deploy-gh-pages@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CUSTOM_DOMAIN: docs.paperless-ngx.com + CONFIG_FILE: mkdocs.yml + EXTRA_PACKAGES: build-base tests-backend: name: "Tests (${{ matrix.python-version }})" @@ -81,15 +99,6 @@ jobs: matrix: python-version: ['3.8', '3.9', '3.10'] fail-fast: false - services: - tika: - image: ghcr.io/paperless-ngx/tika:latest - ports: - - "9998:9998/tcp" - gotenberg: - image: docker.io/gotenberg/gotenberg:7.6 - ports: - - "3000:3000/tcp" env: # Enable Tika end to end testing TIKA_LIVE: 1 @@ -97,12 +106,21 @@ jobs: PAPERLESS_MAIL_TEST_HOST: ${{ secrets.TEST_MAIL_HOST }} PAPERLESS_MAIL_TEST_USER: ${{ secrets.TEST_MAIL_USER }} PAPERLESS_MAIL_TEST_PASSWD: ${{ secrets.TEST_MAIL_PASSWD }} + # Skip Tests which require convert + PAPERLESS_TEST_SKIP_CONVERT: 1 + # Enable Gotenberg end to end testing + GOTENBERG_LIVE: 1 steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 + - + name: Start containers + run: | + docker compose --file ${GITHUB_WORKSPACE}/docker/compose/docker-compose.ci-test.yml pull --quiet + docker compose --file ${GITHUB_WORKSPACE}/docker/compose/docker-compose.ci-test.yml up --detach - name: Install pipenv run: | @@ -154,6 +172,12 @@ jobs: run: | cd src/ pipenv run coveralls --service=github + - + name: Stop containers + if: always() + run: | + docker compose --file ${GITHUB_WORKSPACE}/docker/compose/docker-compose.ci-test.yml logs + docker compose --file ${GITHUB_WORKSPACE}/docker/compose/docker-compose.ci-test.yml down tests-frontend: name: "Tests Frontend" @@ -478,10 +502,9 @@ jobs: - name: Upload release archive id: upload-release-asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: shogo82148/actions-upload-release-asset@v1 with: + github_token: ${{ secrets.GITHUB_TOKEN }} upload_url: ${{ steps.create-release.outputs.upload_url }} asset_path: ./paperless-ngx.tar.xz asset_name: paperless-ngx-${{ steps.get_version.outputs.version }}.tar.xz @@ -523,7 +546,7 @@ jobs: CURRENT_CHANGELOG=`tail --lines +2 changelog.md` echo -e "$CURRENT_CHANGELOG" >> changelog-new.md mv changelog-new.md changelog.md - pipenv run pre-commit --files changelog.md + pipenv run pre-commit run --files changelog.md || true git config --global user.name "github-actions" git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" git commit -am "Changelog ${{ needs.publish-release.outputs.version }} - GHA" diff --git a/.github/workflows/release-chart.yml b/.github/workflows/release-chart.yml new file mode 100644 index 000000000..9e21850ca --- /dev/null +++ b/.github/workflows/release-chart.yml @@ -0,0 +1,31 @@ +--- +name: Release Charts + +on: + push: + tags: + - v* + +jobs: + release_chart: + name: "Release Chart" + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + - name: Install Helm + uses: azure/setup-helm@v3 + with: + version: v3.10.0 + + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.4.1 + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.gitignore b/.gitignore index a93b8139a..ff17f9e33 100644 --- a/.gitignore +++ b/.gitignore @@ -51,8 +51,8 @@ coverage.xml # Django stuff: *.log -# Sphinx documentation -docs/_build/ +# MkDocs documentation +site/ # PyBuilder target/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c9f70ee81..eb45f7224 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,13 +11,14 @@ repos: - id: check-json exclude: "tsconfig.*json" - id: check-yaml + exclude: "charts/paperless-ngx/templates/common.yaml" - id: check-toml - id: check-executables-have-shebangs - id: end-of-file-fixer exclude_types: - svg - pofile - exclude: "(^LICENSE$)" + exclude: "^(LICENSE|charts/paperless-ngx/README.md)$" - id: mixed-line-ending args: - "--fix=lf" @@ -34,7 +35,7 @@ repos: - javascript - ts - markdown - exclude: "(^Pipfile\\.lock$)" + exclude: "(^Pipfile\\.lock$)|(^charts/paperless-ngx/README.md$)" # Python hooks - repo: https://github.com/asottile/reorder_python_imports rev: v3.9.0 diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index 42b4af489..000000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,16 +0,0 @@ -# .readthedocs.yml -# Read the Docs configuration file -# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details - -# Required -version: 2 - -# Build documentation in the docs/ directory with Sphinx -sphinx: - configuration: docs/conf.py - -# Optionally set the version of Python and requirements required to build your docs -python: - version: "3.8" - install: - - requirements: docs/requirements.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 68fc44b84..1e04ca4aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,11 +27,11 @@ Please format and test your code! I know it's a hassle, but it makes sure that y To test your code, execute `pytest` in the src/ directory. This also generates a html coverage report, which you can use to see if you missed anything important during testing. -Before you can run `pytest`, ensure to [properly set up your local environment](https://paperless-ngx.readthedocs.io/en/latest/extending.html#initial-setup-and-first-start). +Before you can run `pytest`, ensure to [properly set up your local environment](https://docs.paperless-ngx.com/development/#initial-setup-and-first-start). ## More info: -... is available in the documentation. https://paperless-ngx.readthedocs.io/en/latest/extending.html +... is available [in the documentation](https://docs.paperless-ngx.com/development). # Merging PRs diff --git a/Dockerfile b/Dockerfile index 8b562e73e..2cb25c0c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,7 +52,7 @@ RUN set -eux \ FROM python:3.9-slim-bullseye as main-app LABEL org.opencontainers.image.authors="paperless-ngx team " -LABEL org.opencontainers.image.documentation="https://paperless-ngx.readthedocs.io/en/latest/" +LABEL org.opencontainers.image.documentation="https://docs.paperless-ngx.com/" LABEL org.opencontainers.image.source="https://github.com/paperless-ngx/paperless-ngx" LABEL org.opencontainers.image.url="https://github.com/paperless-ngx/paperless-ngx" LABEL org.opencontainers.image.licenses="GPL-3.0-only" @@ -72,34 +72,37 @@ COPY --from=jbig2enc-builder /usr/src/jbig2enc/src/*.h /usr/local/include/ # Packages need for running ARG RUNTIME_PACKAGES="\ + # Python + python3 \ + python3-pip \ + python3-setuptools \ + # General utils curl \ - file \ + # Docker specific + gosu \ + # Timezones support + tzdata \ # fonts for text file thumbnail generation fonts-liberation \ gettext \ ghostscript \ gnupg \ - gosu \ icc-profiles-free \ imagemagick \ - media-types \ + # Image processing liblept5 \ - libpq5 \ - libxml2 \ liblcms2-2 \ libtiff5 \ - libxslt1.1 \ libfreetype6 \ libwebp6 \ libopenjp2-7 \ libimagequant0 \ libraqm0 \ - libgnutls30 \ libjpeg62-turbo \ - python3 \ - python3-pip \ - python3-setuptools \ + # PostgreSQL + libpq5 \ postgresql-client \ + # MySQL / MariaDB mariadb-client \ # For Numpy libatlas3-base \ @@ -110,17 +113,23 @@ ARG RUNTIME_PACKAGES="\ tesseract-ocr-fra \ tesseract-ocr-ita \ tesseract-ocr-spa \ - # Suggested for OCRmyPDF - pngquant \ - # Suggested for pikepdf - jbig2dec \ - tzdata \ unpaper \ + pngquant \ + # pikepdf / qpdf + jbig2dec \ + libxml2 \ + libxslt1.1 \ + libgnutls30 \ # Mime type detection + file \ + libmagic1 \ + media-types \ zlib1g \ # Barcode splitter libzbar0 \ - poppler-utils" + poppler-utils \ + # RapidFuzz on armv7 + libatomic1" # Install basic runtime packages. # These change very infrequently diff --git a/Pipfile b/Pipfile index b94110478..e7702898a 100644 --- a/Pipfile +++ b/Pipfile @@ -60,6 +60,9 @@ setproctitle = "*" nltk = "*" pdf2image = "*" flower = "*" +bleach = "*" +# https://www.piwheels.org/project/cryptography/ last built version +cryptography = "==38.0.1" [dev-packages] coveralls = "*" @@ -71,10 +74,10 @@ pytest-django = "*" pytest-env = "*" pytest-sugar = "*" pytest-xdist = "*" -sphinx = "~=5.3" -sphinx_rtd_theme = "*" tox = "*" black = "*" pre-commit = "*" sphinx-autobuild = "*" myst-parser = "*" +imagehash = "*" +mkdocs-material = "*" diff --git a/Pipfile.lock b/Pipfile.lock index b6d73906f..844668913 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9fefc737155e789ced61b41750b4273c7780ac7801c50cf36dc5925be3b85783" + "sha256": "cbfe9920231de6e7f993962efb3cc371abdb6b08975232d4cf64d1bad1b53d7a" }, "pipfile-spec": 6, "requires": {}, @@ -99,6 +99,7 @@ "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac", "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2" ], + "index": "pypi", "markers": "python_version < '3.9'", "version": "==0.2.1" }, @@ -109,6 +110,14 @@ ], "version": "==3.6.4.0" }, + "bleach": { + "hashes": [ + "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a", + "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c" + ], + "index": "pypi", + "version": "==5.0.1" + }, "celery": { "extras": [ "redis" @@ -1766,6 +1775,13 @@ ], "version": "==0.2.5" }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, "websockets": { "hashes": [ "sha256:00213676a2e46b6ebf6045bc11d0f529d9120baa6f58d122b4021ad92adabd41", @@ -2074,6 +2090,7 @@ "version": "==0.4.6" }, "coverage": { + "extras": [], "hashes": [ "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79", "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a", @@ -2198,6 +2215,13 @@ "index": "pypi", "version": "==3.8.0" }, + "ghp-import": { + "hashes": [ + "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", + "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343" + ], + "version": "==2.1.0" + }, "identify": { "hashes": [ "sha256:48b7925fe122720088aeb7a6c34f17b27e706b72c61070f27fe3789094233440", @@ -2214,6 +2238,14 @@ "markers": "python_version >= '3.5'", "version": "==3.4" }, + "imagehash": { + "hashes": [ + "sha256:5ad9a5cde14fe255745a8245677293ac0d67f09c330986a351f34b614ba62fb5", + "sha256:7038d1b7f9e0585beb3dd8c0a956f02b95a346c0b5f24a9e8cc03ebadaf0aa70" + ], + "index": "pypi", + "version": "==4.3.1" + }, "imagesize": { "hashes": [ "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", @@ -2222,6 +2254,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.4.1" }, + "importlib-metadata": { + "hashes": [ + "sha256:d5059f9f1e8e41f80e9c56c2ee58811450c31984dfa625329ffd7c0dad88a73b", + "sha256:d84d17e21670ec07990e1044a99efe8d615d860fd176fc29ef5c306068fda313" + ], + "markers": "python_version < '3.10'", + "version": "==5.1.0" + }, "iniconfig": { "hashes": [ "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", @@ -2243,6 +2283,14 @@ ], "version": "==2.6.3" }, + "markdown": { + "hashes": [ + "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874", + "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621" + ], + "markers": "python_version >= '3.6'", + "version": "==3.3.7" + }, "markdown-it-py": { "hashes": [ "sha256:93de681e5c021a432c63147656fe21790bc01231e0cd2da73626f1aa3ac0fe27", @@ -2313,6 +2361,38 @@ "markers": "python_version >= '3.7'", "version": "==0.1.2" }, + "mergedeep": { + "hashes": [ + "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", + "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307" + ], + "markers": "python_version >= '3.6'", + "version": "==1.3.4" + }, + "mkdocs": { + "hashes": [ + "sha256:8947af423a6d0facf41ea1195b8e1e8c85ad94ac95ae307fe11232e0424b11c5", + "sha256:c8856a832c1e56702577023cd64cc5f84948280c1c0fcc6af4cd39006ea6aa8c" + ], + "markers": "python_version >= '3.7'", + "version": "==1.4.2" + }, + "mkdocs-material": { + "hashes": [ + "sha256:b0ea0513fd8cab323e8a825d6692ea07fa83e917bb5db042e523afecc7064ab7", + "sha256:c907b4b052240a5778074a30a78f31a1f8ff82d7012356dc26898b97559f082e" + ], + "index": "pypi", + "version": "==8.5.11" + }, + "mkdocs-material-extensions": { + "hashes": [ + "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93", + "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945" + ], + "markers": "python_version >= '3.7'", + "version": "==1.1.1" + }, "mypy-extensions": { "hashes": [ "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", @@ -2336,6 +2416,40 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", "version": "==1.7.0" }, + "numpy": { + "hashes": [ + "sha256:0fe563fc8ed9dc4474cbf70742673fc4391d70f4363f917599a7fa99f042d5a8", + "sha256:12ac457b63ec8ded85d85c1e17d85efd3c2b0967ca39560b307a35a6703a4735", + "sha256:2341f4ab6dba0834b685cce16dad5f9b6606ea8a00e6da154f5dbded70fdc4dd", + "sha256:296d17aed51161dbad3c67ed6d164e51fcd18dbcd5dd4f9d0a9c6055dce30810", + "sha256:488a66cb667359534bc70028d653ba1cf307bae88eab5929cd707c761ff037db", + "sha256:4d52914c88b4930dafb6c48ba5115a96cbab40f45740239d9f4159c4ba779962", + "sha256:5e13030f8793e9ee42f9c7d5777465a560eb78fa7e11b1c053427f2ccab90c79", + "sha256:61be02e3bf810b60ab74e81d6d0d36246dbfb644a462458bb53b595791251911", + "sha256:7607b598217745cc40f751da38ffd03512d33ec06f3523fb0b5f82e09f6f676d", + "sha256:7a70a7d3ce4c0e9284e92285cba91a4a3f5214d87ee0e95928f3614a256a1488", + "sha256:7ab46e4e7ec63c8a5e6dbf5c1b9e1c92ba23a7ebecc86c336cb7bf3bd2fb10e5", + "sha256:8981d9b5619569899666170c7c9748920f4a5005bf79c72c07d08c8a035757b0", + "sha256:8c053d7557a8f022ec823196d242464b6955a7e7e5015b719e76003f63f82d0f", + "sha256:926db372bc4ac1edf81cfb6c59e2a881606b409ddc0d0920b988174b2e2a767f", + "sha256:95d79ada05005f6f4f337d3bb9de8a7774f259341c70bc88047a1f7b96a4bcb2", + "sha256:95de7dc7dc47a312f6feddd3da2500826defdccbc41608d0031276a24181a2c0", + "sha256:a0882323e0ca4245eb0a3d0a74f88ce581cc33aedcfa396e415e5bba7bf05f68", + "sha256:a8365b942f9c1a7d0f0dc974747d99dd0a0cdfc5949a33119caf05cb314682d3", + "sha256:a8aae2fb3180940011b4862b2dd3756616841c53db9734b27bb93813cd79fce6", + "sha256:c237129f0e732885c9a6076a537e974160482eab8f10db6292e92154d4c67d71", + "sha256:c67b833dbccefe97cdd3f52798d430b9d3430396af7cdb2a0c32954c3ef73894", + "sha256:ce03305dd694c4873b9429274fd41fc7eb4e0e4dea07e0af97a933b079a5814f", + "sha256:d331afac87c92373826af83d2b2b435f57b17a5c74e6268b79355b970626e329", + "sha256:dada341ebb79619fe00a291185bba370c9803b1e1d7051610e01ed809ef3a4ba", + "sha256:ed2cc92af0efad20198638c69bb0fc2870a58dabfba6eb722c933b48556c686c", + "sha256:f260da502d7441a45695199b4e7fd8ca87db659ba1c78f2bbf31f934fe76ae0e", + "sha256:f2f390aa4da44454db40a1f0201401f9036e8d578a25f01a6e237cea238337ef", + "sha256:f76025acc8e2114bb664294a07ede0727aa75d63a06d2fae96bf29a81747e4a7" + ], + "index": "pypi", + "version": "==1.23.4" + }, "packaging": { "hashes": [ "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", @@ -2352,6 +2466,73 @@ "markers": "python_version >= '3.7'", "version": "==0.10.1" }, + "pillow": { + "hashes": [ + "sha256:03150abd92771742d4a8cd6f2fa6246d847dcd2e332a18d0c15cc75bf6703040", + "sha256:073adb2ae23431d3b9bcbcff3fe698b62ed47211d0716b067385538a1b0f28b8", + "sha256:0b07fffc13f474264c336298d1b4ce01d9c5a011415b79d4ee5527bb69ae6f65", + "sha256:0b7257127d646ff8676ec8a15520013a698d1fdc48bc2a79ba4e53df792526f2", + "sha256:12ce4932caf2ddf3e41d17fc9c02d67126935a44b86df6a206cf0d7161548627", + "sha256:15c42fb9dea42465dfd902fb0ecf584b8848ceb28b41ee2b58f866411be33f07", + "sha256:18498994b29e1cf86d505edcb7edbe814d133d2232d256db8c7a8ceb34d18cef", + "sha256:1c7c8ae3864846fc95f4611c78129301e203aaa2af813b703c55d10cc1628535", + "sha256:22b012ea2d065fd163ca096f4e37e47cd8b59cf4b0fd47bfca6abb93df70b34c", + "sha256:276a5ca930c913f714e372b2591a22c4bd3b81a418c0f6635ba832daec1cbcfc", + "sha256:2e0918e03aa0c72ea56edbb00d4d664294815aa11291a11504a377ea018330d3", + "sha256:3033fbe1feb1b59394615a1cafaee85e49d01b51d54de0cbf6aa8e64182518a1", + "sha256:3168434d303babf495d4ba58fc22d6604f6e2afb97adc6a423e917dab828939c", + "sha256:32a44128c4bdca7f31de5be641187367fe2a450ad83b833ef78910397db491aa", + "sha256:3dd6caf940756101205dffc5367babf288a30043d35f80936f9bfb37f8355b32", + "sha256:40e1ce476a7804b0fb74bcfa80b0a2206ea6a882938eaba917f7a0f004b42502", + "sha256:41e0051336807468be450d52b8edd12ac60bebaa97fe10c8b660f116e50b30e4", + "sha256:4390e9ce199fc1951fcfa65795f239a8a4944117b5935a9317fb320e7767b40f", + "sha256:502526a2cbfa431d9fc2a079bdd9061a2397b842bb6bc4239bb176da00993812", + "sha256:51e0e543a33ed92db9f5ef69a0356e0b1a7a6b6a71b80df99f1d181ae5875636", + "sha256:57751894f6618fd4308ed8e0c36c333e2f5469744c34729a27532b3db106ee20", + "sha256:5d77adcd56a42d00cc1be30843d3426aa4e660cab4a61021dc84467123f7a00c", + "sha256:655a83b0058ba47c7c52e4e2df5ecf484c1b0b0349805896dd350cbc416bdd91", + "sha256:68943d632f1f9e3dce98908e873b3a090f6cba1cbb1b892a9e8d97c938871fbe", + "sha256:6c738585d7a9961d8c2821a1eb3dcb978d14e238be3d70f0a706f7fa9316946b", + "sha256:73bd195e43f3fadecfc50c682f5055ec32ee2c933243cafbfdec69ab1aa87cad", + "sha256:772a91fc0e03eaf922c63badeca75e91baa80fe2f5f87bdaed4280662aad25c9", + "sha256:77ec3e7be99629898c9a6d24a09de089fa5356ee408cdffffe62d67bb75fdd72", + "sha256:7db8b751ad307d7cf238f02101e8e36a128a6cb199326e867d1398067381bff4", + "sha256:801ec82e4188e935c7f5e22e006d01611d6b41661bba9fe45b60e7ac1a8f84de", + "sha256:82409ffe29d70fd733ff3c1025a602abb3e67405d41b9403b00b01debc4c9a29", + "sha256:828989c45c245518065a110434246c44a56a8b2b2f6347d1409c787e6e4651ee", + "sha256:829f97c8e258593b9daa80638aee3789b7df9da5cf1336035016d76f03b8860c", + "sha256:871b72c3643e516db4ecf20efe735deb27fe30ca17800e661d769faab45a18d7", + "sha256:89dca0ce00a2b49024df6325925555d406b14aa3efc2f752dbb5940c52c56b11", + "sha256:90fb88843d3902fe7c9586d439d1e8c05258f41da473952aa8b328d8b907498c", + "sha256:97aabc5c50312afa5e0a2b07c17d4ac5e865b250986f8afe2b02d772567a380c", + "sha256:9aaa107275d8527e9d6e7670b64aabaaa36e5b6bd71a1015ddd21da0d4e06448", + "sha256:9f47eabcd2ded7698106b05c2c338672d16a6f2a485e74481f524e2a23c2794b", + "sha256:a0a06a052c5f37b4ed81c613a455a81f9a3a69429b4fd7bb913c3fa98abefc20", + "sha256:ab388aaa3f6ce52ac1cb8e122c4bd46657c15905904b3120a6248b5b8b0bc228", + "sha256:ad58d27a5b0262c0c19b47d54c5802db9b34d38bbf886665b626aff83c74bacd", + "sha256:ae5331c23ce118c53b172fa64a4c037eb83c9165aba3a7ba9ddd3ec9fa64a699", + "sha256:af0372acb5d3598f36ec0914deed2a63f6bcdb7b606da04dc19a88d31bf0c05b", + "sha256:afa4107d1b306cdf8953edde0534562607fe8811b6c4d9a486298ad31de733b2", + "sha256:b03ae6f1a1878233ac620c98f3459f79fd77c7e3c2b20d460284e1fb370557d4", + "sha256:b0915e734b33a474d76c28e07292f196cdf2a590a0d25bcc06e64e545f2d146c", + "sha256:b4012d06c846dc2b80651b120e2cdd787b013deb39c09f407727ba90015c684f", + "sha256:b472b5ea442148d1c3e2209f20f1e0bb0eb556538690fa70b5e1f79fa0ba8dc2", + "sha256:b59430236b8e58840a0dfb4099a0e8717ffb779c952426a69ae435ca1f57210c", + "sha256:b90f7616ea170e92820775ed47e136208e04c967271c9ef615b6fbd08d9af0e3", + "sha256:b9a65733d103311331875c1dca05cb4606997fd33d6acfed695b1232ba1df193", + "sha256:bac18ab8d2d1e6b4ce25e3424f709aceef668347db8637c2296bcf41acb7cf48", + "sha256:bca31dd6014cb8b0b2db1e46081b0ca7d936f856da3b39744aef499db5d84d02", + "sha256:be55f8457cd1eac957af0c3f5ece7bc3f033f89b114ef30f710882717670b2a8", + "sha256:c7025dce65566eb6e89f56c9509d4f628fddcedb131d9465cacd3d8bac337e7e", + "sha256:c935a22a557a560108d780f9a0fc426dd7459940dc54faa49d83249c8d3e760f", + "sha256:dbb8e7f2abee51cef77673be97760abff1674ed32847ce04b4af90f610144c7b", + "sha256:e6ea6b856a74d560d9326c0f5895ef8050126acfdc7ca08ad703eb0081e82b74", + "sha256:ebf2029c1f464c59b8bdbe5143c79fa2045a581ac53679733d3a91d400ff9efb", + "sha256:f1ff2ee69f10f13a9596480335f406dd1f70c3650349e2be67ca3139280cade0" + ], + "index": "pypi", + "version": "==9.3.0" + }, "platformdirs": { "hashes": [ "sha256:0cb405749187a194f444c25c82ef7225232f11564721eabffc6ec70df83b11cb", @@ -2400,6 +2581,14 @@ "markers": "python_version >= '3.6'", "version": "==2.13.0" }, + "pymdown-extensions": { + "hashes": [ + "sha256:0f8fb7b74a37a61cc34e90b2c91865458b713ec774894ffad64353a5fce85cfc", + "sha256:ac698c15265680db5eb13cd4342abfcde2079ac01e5486028f47a1b41547b859" + ], + "markers": "python_version >= '3.7'", + "version": "==9.9" + }, "pyparsing": { "hashes": [ "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", @@ -2471,6 +2660,37 @@ ], "version": "==2022.6" }, + "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" + ], + "markers": "python_version >= '3.8'", + "version": "==1.4.1" + }, "pyyaml": { "hashes": [ "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", @@ -2516,6 +2736,14 @@ ], "version": "==6.0" }, + "pyyaml-env-tag": { + "hashes": [ + "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", + "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069" + ], + "markers": "python_version >= '3.6'", + "version": "==0.1" + }, "requests": { "hashes": [ "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", @@ -2524,6 +2752,35 @@ "markers": "python_version >= '3.7' and python_version < '4'", "version": "==2.28.1" }, + "scipy": { + "hashes": [ + "sha256:02b567e722d62bddd4ac253dafb01ce7ed8742cf8031aea030a41414b86c1125", + "sha256:1166514aa3bbf04cb5941027c6e294a000bba0cf00f5cdac6c77f2dad479b434", + "sha256:1da52b45ce1a24a4a22db6c157c38b39885a990a566748fc904ec9f03ed8c6ba", + "sha256:23b22fbeef3807966ea42d8163322366dd89da9bebdc075da7034cee3a1441ca", + "sha256:28d2cab0c6ac5aa131cc5071a3a1d8e1366dad82288d9ec2ca44df78fb50e649", + "sha256:2ef0fbc8bcf102c1998c1f16f15befe7cffba90895d6e84861cd6c6a33fb54f6", + "sha256:3b69b90c9419884efeffaac2c38376d6ef566e6e730a231e15722b0ab58f0328", + "sha256:4b93ec6f4c3c4d041b26b5f179a6aab8f5045423117ae7a45ba9710301d7e462", + "sha256:4e53a55f6a4f22de01ffe1d2f016e30adedb67a699a310cdcac312806807ca81", + "sha256:6311e3ae9cc75f77c33076cb2794fb0606f14c8f1b1c9ff8ce6005ba2c283621", + "sha256:65b77f20202599c51eb2771d11a6b899b97989159b7975e9b5259594f1d35ef4", + "sha256:6cc6b33139eb63f30725d5f7fa175763dc2df6a8f38ddf8df971f7c345b652dc", + "sha256:70de2f11bf64ca9921fda018864c78af7147025e467ce9f4a11bc877266900a6", + "sha256:70ebc84134cf0c504ce6a5f12d6db92cb2a8a53a49437a6bb4edca0bc101f11c", + "sha256:83606129247e7610b58d0e1e93d2c5133959e9cf93555d3c27e536892f1ba1f2", + "sha256:93d07494a8900d55492401917a119948ed330b8c3f1d700e0b904a578f10ead4", + "sha256:9c4e3ae8a716c8b3151e16c05edb1daf4cb4d866caa385e861556aff41300c14", + "sha256:9dd4012ac599a1e7eb63c114d1eee1bcfc6dc75a29b589ff0ad0bb3d9412034f", + "sha256:9e3fb1b0e896f14a85aa9a28d5f755daaeeb54c897b746df7a55ccb02b340f33", + "sha256:a0aa8220b89b2e3748a2836fbfa116194378910f1a6e78e4675a095bcd2c762d", + "sha256:d3b3c8924252caaffc54d4a99f1360aeec001e61267595561089f8b5900821bb", + "sha256:e013aed00ed776d790be4cb32826adb72799c61e318676172495383ba4570aa4", + "sha256:f3e7a8867f307e3359cc0ed2c63b61a1e33a19080f92fe377bc7d49f646f2ec1" + ], + "index": "pypi", + "version": "==1.8.1" + }, "setuptools": { "hashes": [ "sha256:d0b9a8433464d5800cbe05094acf5c6d52a91bfac9b52bcfc4d41382be5d5d31", @@ -2552,7 +2809,6 @@ "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d", "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5" ], - "index": "pypi", "version": "==5.3.0" }, "sphinx-autobuild": { @@ -2691,6 +2947,45 @@ ], "markers": "python_version >= '3.6'", "version": "==20.16.6" + }, + "watchdog": { + "hashes": [ + "sha256:083171652584e1b8829581f965b9b7723ca5f9a2cd7e20271edf264cfd7c1412", + "sha256:117ffc6ec261639a0209a3252546b12800670d4bf5f84fbd355957a0595fe654", + "sha256:186f6c55abc5e03872ae14c2f294a153ec7292f807af99f57611acc8caa75306", + "sha256:195fc70c6e41237362ba720e9aaf394f8178bfc7fa68207f112d108edef1af33", + "sha256:226b3c6c468ce72051a4c15a4cc2ef317c32590d82ba0b330403cafd98a62cfd", + "sha256:247dcf1df956daa24828bfea5a138d0e7a7c98b1a47cf1fa5b0c3c16241fcbb7", + "sha256:255bb5758f7e89b1a13c05a5bceccec2219f8995a3a4c4d6968fe1de6a3b2892", + "sha256:43ce20ebb36a51f21fa376f76d1d4692452b2527ccd601950d69ed36b9e21609", + "sha256:4f4e1c4aa54fb86316a62a87b3378c025e228178d55481d30d857c6c438897d6", + "sha256:5952135968519e2447a01875a6f5fc8c03190b24d14ee52b0f4b1682259520b1", + "sha256:64a27aed691408a6abd83394b38503e8176f69031ca25d64131d8d640a307591", + "sha256:6b17d302850c8d412784d9246cfe8d7e3af6bcd45f958abb2d08a6f8bedf695d", + "sha256:70af927aa1613ded6a68089a9262a009fbdf819f46d09c1a908d4b36e1ba2b2d", + "sha256:7a833211f49143c3d336729b0020ffd1274078e94b0ae42e22f596999f50279c", + "sha256:8250546a98388cbc00c3ee3cc5cf96799b5a595270dfcfa855491a64b86ef8c3", + "sha256:97f9752208f5154e9e7b76acc8c4f5a58801b338de2af14e7e181ee3b28a5d39", + "sha256:9f05a5f7c12452f6a27203f76779ae3f46fa30f1dd833037ea8cbc2887c60213", + "sha256:a735a990a1095f75ca4f36ea2ef2752c99e6ee997c46b0de507ba40a09bf7330", + "sha256:ad576a565260d8f99d97f2e64b0f97a48228317095908568a9d5c786c829d428", + "sha256:b530ae007a5f5d50b7fbba96634c7ee21abec70dc3e7f0233339c81943848dc1", + "sha256:bfc4d351e6348d6ec51df007432e6fe80adb53fd41183716017026af03427846", + "sha256:d3dda00aca282b26194bdd0adec21e4c21e916956d972369359ba63ade616153", + "sha256:d9820fe47c20c13e3c9dd544d3706a2a26c02b2b43c993b62fcd8011bcc0adb3", + "sha256:ed80a1628cee19f5cfc6bb74e173f1b4189eb532e705e2a13e3250312a62e0c9", + "sha256:ee3e38a6cc050a8830089f79cbec8a3878ec2fe5160cdb2dc8ccb6def8552658" + ], + "index": "pypi", + "version": "==2.1.9" + }, + "zipp": { + "hashes": [ + "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1", + "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8" + ], + "markers": "python_version < '3.9'", + "version": "==3.10.0" } } } diff --git a/README.md b/README.md index 8b1eb5e4a..4dc09d787 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ [![ci](https://github.com/paperless-ngx/paperless-ngx/workflows/ci/badge.svg)](https://github.com/paperless-ngx/paperless-ngx/actions) [![Crowdin](https://badges.crowdin.net/paperless-ngx/localized.svg)](https://crowdin.com/project/paperless-ngx) -[![Documentation Status](https://readthedocs.org/projects/paperless-ngx/badge/?version=latest)](https://paperless-ngx.readthedocs.io/en/latest/?badge=latest) +[![Documentation Status](https://img.shields.io/github/deployments/paperless-ngx/paperless-ngx/github-pages?label=docs)](https://docs.paperless-ngx.com) [![Coverage Status](https://coveralls.io/repos/github/paperless-ngx/paperless-ngx/badge.svg?branch=master)](https://coveralls.io/github/paperless-ngx/paperless-ngx?branch=master) -[![Chat on Matrix](https://matrix.to/img/matrix-badge.svg)](https://matrix.to/#/#paperless:adnidor.de) +[![Chat on Matrix](https://matrix.to/img/matrix-badge.svg)](https://matrix.to/#/%23paperlessngx%3Amatrix.org) +[![demo](https://cronitor.io/badges/ve7ItY/production/W5E_B9jkelG9ZbDiNHUPQEVH3MY.svg)](https://demo.paperless-ngx.com)

@@ -32,13 +33,13 @@ A demo is available at [demo.paperless-ngx.com](https://demo.paperless-ngx.com) # Features -![Dashboard](https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docs/_static/screenshots/documents-wchrome.png#gh-light-mode-only) -![Dashboard](https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docs/_static/screenshots/documents-wchrome-dark.png#gh-dark-mode-only) +![Dashboard](https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docs/assets/screenshots/documents-smallcards.png#gh-light-mode-only) +![Dashboard](https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docs/assets/screenshots/documents-smallcards-dark.png#gh-dark-mode-only) - Organize and index your scanned documents with tags, correspondents, types, and more. - Performs OCR on your documents, adds selectable text to image only documents and adds tags, correspondents and document types to your documents. - Supports PDF documents, images, plain text files, and Office documents (Word, Excel, Powerpoint, and LibreOffice equivalents). - - Office document support is optional and provided by Apache Tika (see [configuration](https://paperless-ngx.readthedocs.io/en/latest/configuration.html#tika-settings)) + - Office document support is optional and provided by Apache Tika (see [configuration](https://docs.paperless-ngx.com/configuration/#tika)) - Paperless stores your documents plain on disk. Filenames and folders are managed by paperless and their format can be configured freely. - Single page application front end. - Includes a dashboard that shows basic statistics and has document upload. @@ -56,7 +57,7 @@ A demo is available at [demo.paperless-ngx.com](https://demo.paperless-ngx.com) - Paperless-ngx learns from your documents and will be able to automatically assign tags, correspondents and types to documents once you've stored a few documents in paperless. - Optimized for multi core systems: Paperless-ngx consumes multiple documents in parallel. - The integrated sanity checker makes sure that your document archive is in good health. -- [More screenshots are available in the documentation](https://paperless-ngx.readthedocs.io/en/latest/screenshots.html). +- [More screenshots are available in the documentation](https://docs.paperless-ngx.com/#screenshots). # Getting started @@ -68,19 +69,19 @@ If you'd like to jump right in, you can configure a docker-compose environment w bash -c "$(curl -L https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)" ``` -Alternatively, you can install the dependencies and setup apache and a database server yourself. The [documentation](https://paperless-ngx.readthedocs.io/en/latest/setup.html#installation) has a step by step guide on how to do it. +Alternatively, you can install the dependencies and setup apache and a database server yourself. The [documentation](https://docs.paperless-ngx.com/setup/#installation) has a step by step guide on how to do it. -Migrating from Paperless-ng is easy, just drop in the new docker image! See the [documentation on migrating](https://paperless-ngx.readthedocs.io/en/latest/setup.html#migrating-from-paperless-ng) for more details. +Migrating from Paperless-ng is easy, just drop in the new docker image! See the [documentation on migrating](https://docs.paperless-ngx.com/setup/#migrating-to-paperless-ngx) for more details. ### Documentation -The documentation for Paperless-ngx is available on [ReadTheDocs](https://paperless-ngx.readthedocs.io/). +The documentation for Paperless-ngx is available at [https://docs.paperless-ngx.com](https://docs.paperless-ngx.com/). # Contributing -If you feel like contributing to the project, please do! Bug fixes, enhancements, visual fixes etc. are always welcome. If you want to implement something big: Please start a discussion about that! The [documentation](https://paperless-ngx.readthedocs.io/en/latest/extending.html) has some basic information on how to get started. +If you feel like contributing to the project, please do! Bug fixes, enhancements, visual fixes etc. are always welcome. If you want to implement something big: Please start a discussion about that! The [documentation](https://docs.paperless-ngx.com/development/) has some basic information on how to get started. ## Community Support @@ -105,6 +106,7 @@ Paperless has been around a while now, and people are starting to build stuff on - [Paperless App](https://github.com/bauerj/paperless_app): An Android/iOS app for Paperless-ngx. Also works with the original Paperless and Paperless-ng. - [Paperless Share](https://github.com/qcasey/paperless_share). Share any files from your Android application with paperless. Very simple, but works with all of the mobile scanning apps out there that allow you to share scanned documents. - [Scan to Paperless](https://github.com/sbrunner/scan-to-paperless): Scan and prepare (crop, deskew, OCR, ...) your documents for Paperless. +- [Paperless Mobile](https://github.com/astubenbord/paperless-mobile): A modern, feature rich mobile application for Paperless. These projects also exist, but their status and compatibility with paperless-ngx is unknown. diff --git a/charts/paperless-ngx/.helmignore b/charts/paperless-ngx/.helmignore new file mode 100644 index 000000000..4379e2b30 --- /dev/null +++ b/charts/paperless-ngx/.helmignore @@ -0,0 +1,26 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +# OWNERS file for Kubernetes +OWNERS +# helm-docs templates +*.gotmpl diff --git a/charts/paperless-ngx/Chart.yaml b/charts/paperless-ngx/Chart.yaml new file mode 100644 index 000000000..60d8b0b1d --- /dev/null +++ b/charts/paperless-ngx/Chart.yaml @@ -0,0 +1,35 @@ +--- +apiVersion: v2 +appVersion: "1.9.2" +description: Paperless-ngx - Index and archive all of your scanned paper documents +name: paperless +version: 10.0.0 +kubeVersion: ">=1.16.0-0" +keywords: + - paperless + - paperless-ngx + - dms + - document +home: https://github.com/paperless-ngx/paperless-ngx/tree/main/charts/paperless-ngx +icon: https://github.com/paperless-ngx/paperless-ngx/raw/main/resources/logo/web/svg/square.svg +sources: + - https://github.com/paperless-ngx/paperless-ngx +maintainers: + - name: Paperless-ngx maintainers +dependencies: + - name: common + repository: https://library-charts.k8s-at-home.com + version: 4.5.2 + - name: postgresql + version: 11.6.12 + repository: https://charts.bitnami.com/bitnami + condition: postgresql.enabled + - name: redis + version: 16.13.1 + repository: https://charts.bitnami.com/bitnami + condition: redis.enabled +deprecated: false +annotations: + artifacthub.io/changes: | + - kind: changed + description: Moved to Paperless-ngx ownership diff --git a/charts/paperless-ngx/LICENSE b/charts/paperless-ngx/LICENSE new file mode 100644 index 000000000..056d3dab3 --- /dev/null +++ b/charts/paperless-ngx/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 k8s@Home + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/charts/paperless-ngx/README.md b/charts/paperless-ngx/README.md new file mode 100644 index 000000000..be49a25d0 --- /dev/null +++ b/charts/paperless-ngx/README.md @@ -0,0 +1,50 @@ +# paperless + +![Version: 10.0.0](https://img.shields.io/badge/Version-10.0.0-informational?style=flat-square) ![AppVersion: 1.9.2](https://img.shields.io/badge/AppVersion-1.9.2-informational?style=flat-square) + +Paperless-ngx - Index and archive all of your scanned paper documents + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Paperless-ngx maintainers | | | + +## Source Code + +* + +## Requirements + +Kubernetes: `>=1.16.0-0` + +| Repository | Name | Version | +|------------|------|---------| +| https://charts.bitnami.com/bitnami | postgresql | 11.6.12 | +| https://charts.bitnami.com/bitnami | redis | 16.13.1 | +| https://library-charts.k8s-at-home.com | common | 4.5.2 | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| env | object | See below | See the following files for additional environment variables: https://github.com/paperless-ngx/paperless-ngx/tree/main/docker/compose/ https://github.com/paperless-ngx/paperless-ngx/blob/main/paperless.conf.example | +| env.COMPOSE_PROJECT_NAME | string | `"paperless"` | Project name | +| env.PAPERLESS_DBHOST | string | `nil` | Database host to use | +| env.PAPERLESS_OCR_LANGUAGE | string | `"eng"` | OCR languages to install | +| env.PAPERLESS_PORT | int | `8000` | Port to use | +| env.PAPERLESS_REDIS | string | `nil` | Redis to use | +| image.pullPolicy | string | `"IfNotPresent"` | image pull policy | +| image.repository | string | `"ghcr.io/paperless-ngx/paperless-ngx"` | image repository | +| image.tag | string | chart.appVersion | image tag | +| ingress.main | object | See values.yaml | Enable and configure ingress settings for the chart under this key. | +| persistence.consume | object | See values.yaml | Configure volume to monitor for new documents. | +| persistence.data | object | See values.yaml | Configure persistence for data. | +| persistence.export | object | See values.yaml | Configure export volume. | +| persistence.media | object | See values.yaml | Configure persistence for media. | +| postgresql | object | See values.yaml | Enable and configure postgresql database subchart under this key. For more options see [postgresql chart documentation](https://github.com/bitnami/charts/tree/master/bitnami/postgresql) | +| redis | object | See values.yaml | Enable and configure redis subchart under this key. For more options see [redis chart documentation](https://github.com/bitnami/charts/tree/master/bitnami/redis) | +| service | object | See values.yaml | Configures service settings for the chart. | + diff --git a/charts/paperless-ngx/README_CONFIG.md.gotmpl b/charts/paperless-ngx/README_CONFIG.md.gotmpl new file mode 100644 index 000000000..ba63bd5f6 --- /dev/null +++ b/charts/paperless-ngx/README_CONFIG.md.gotmpl @@ -0,0 +1,8 @@ +{{- define "custom.custom.configuration.header" -}} +## Custom configuration +{{- end -}} + +{{- define "custom.custom.configuration" -}} +{{ template "custom.custom.configuration.header" . }} +N/A +{{- end -}} diff --git a/charts/paperless-ngx/ci/ct-values.yaml b/charts/paperless-ngx/ci/ct-values.yaml new file mode 100644 index 000000000..3af930887 --- /dev/null +++ b/charts/paperless-ngx/ci/ct-values.yaml @@ -0,0 +1,26 @@ +env: + PAPERLESS_REDIS: redis://paperless-redis-headless:6379 + +persistence: + data: + enabled: true + type: emptyDir + media: + enabled: true + type: emptyDir + consume: + enabled: true + type: emptyDir + export: + enabled: true + type: emptyDir + +redis: + enabled: true + architecture: standalone + auth: + enabled: false + master: + persistence: + enabled: false + fullnameOverride: paperless-redis diff --git a/charts/paperless-ngx/templates/NOTES.txt b/charts/paperless-ngx/templates/NOTES.txt new file mode 100644 index 000000000..d16476cad --- /dev/null +++ b/charts/paperless-ngx/templates/NOTES.txt @@ -0,0 +1,4 @@ +{{- include "common.notes.defaultNotes" . }} +2. Create a super user by running the command: + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "common.names.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl exec -it --namespace {{ .Release.Namespace }} $POD_NAME -- bash -c "python manage.py createsuperuser" diff --git a/charts/paperless-ngx/templates/common.yaml b/charts/paperless-ngx/templates/common.yaml new file mode 100644 index 000000000..13801ed4f --- /dev/null +++ b/charts/paperless-ngx/templates/common.yaml @@ -0,0 +1,11 @@ +{{/* Make sure all variables are set properly */}} +{{- include "common.values.setup" . }} + +{{/* Append the hardcoded settings */}} +{{- define "paperless.harcodedValues" -}} +env: + PAPERLESS_URL: http{{if ne ( len .Values.ingress.main.tls ) 0 }}s{{end}}://{{ (first .Values.ingress.main.hosts).host }} +{{- end -}} +{{- $_ := merge .Values (include "paperless.harcodedValues" . | fromYaml) -}} + +{{ include "common.all" . }} diff --git a/charts/paperless-ngx/values.yaml b/charts/paperless-ngx/values.yaml new file mode 100644 index 000000000..cde42deed --- /dev/null +++ b/charts/paperless-ngx/values.yaml @@ -0,0 +1,107 @@ +# +# IMPORTANT NOTE +# +# This chart inherits from our common library chart. You can check the default values/options here: +# https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common/values.yaml +# + +image: + # -- image repository + repository: ghcr.io/paperless-ngx/paperless-ngx + # -- image pull policy + pullPolicy: IfNotPresent + # -- image tag + # @default -- chart.appVersion + tag: + +# -- See the following files for additional environment variables: +# https://github.com/paperless-ngx/paperless-ngx/tree/main/docker/compose/ +# https://github.com/paperless-ngx/paperless-ngx/blob/main/paperless.conf.example +# @default -- See below +env: + # -- Project name + COMPOSE_PROJECT_NAME: paperless + # -- Redis to use + PAPERLESS_REDIS: + # -- OCR languages to install + PAPERLESS_OCR_LANGUAGE: eng + # USERMAP_UID: 1000 + # USERMAP_GID: 1000 + # PAPERLESS_TIME_ZONE: Europe/London + # -- Database host to use + PAPERLESS_DBHOST: + # -- Port to use + PAPERLESS_PORT: 8000 + # -- Username for the root user + # PAPERLESS_ADMIN_USER: admin + # -- Password for the root user + # PAPERLESS_ADMIN_PASSWORD: admin + # PAPERLESS_URL: + +# -- Configures service settings for the chart. +# @default -- See values.yaml +service: + main: + ports: + http: + port: 8000 + +ingress: + # -- Enable and configure ingress settings for the chart under this key. + # @default -- See values.yaml + main: + enabled: false + +persistence: + # -- Configure persistence for data. + # @default -- See values.yaml + data: + enabled: false + mountPath: /usr/src/paperless/data + accessMode: ReadWriteOnce + emptyDir: + enabled: false + # -- Configure persistence for media. + # @default -- See values.yaml + media: + enabled: false + mountPath: /usr/src/paperless/media + accessMode: ReadWriteOnce + emptyDir: + enabled: false + # -- Configure volume to monitor for new documents. + # @default -- See values.yaml + consume: + enabled: false + mountPath: /usr/src/paperless/consume + accessMode: ReadWriteOnce + emptyDir: + enabled: false + # -- Configure export volume. + # @default -- See values.yaml + export: + enabled: false + mountPath: /usr/src/paperless/export + accessMode: ReadWriteOnce + emptyDir: + enabled: false + +# -- Enable and configure postgresql database subchart under this key. +# For more options see [postgresql chart documentation](https://github.com/bitnami/charts/tree/master/bitnami/postgresql) +# @default -- See values.yaml +postgresql: + enabled: false + postgresqlUsername: paperless + postgresqlPassword: paperless + postgresqlDatabase: paperless + persistence: + enabled: false + # storageClass: "" + +# -- Enable and configure redis subchart under this key. +# For more options see [redis chart documentation](https://github.com/bitnami/charts/tree/master/bitnami/redis) +# @default -- See values.yaml +redis: + enabled: false + auth: + enabled: false diff --git a/docker/compose/docker-compose.ci-test.yml b/docker/compose/docker-compose.ci-test.yml new file mode 100644 index 000000000..b1b8d2179 --- /dev/null +++ b/docker/compose/docker-compose.ci-test.yml @@ -0,0 +1,25 @@ +# docker-compose file for running paperless testing with actual gotenberg +# and Tika containers for a more end to end test of the Tika related functionality +# Can be used locally or by the CI to start the nessecary containers with the +# correct networking for the tests + +version: "3.7" +services: + gotenberg: + image: docker.io/gotenberg/gotenberg:7.6 + hostname: gotenberg + container_name: gotenberg + network_mode: host + restart: unless-stopped + # The gotenberg chromium route is used to convert .eml files. We do not + # want to allow external content like tracking pixels or even javascript. + command: + - "gotenberg" + - "--chromium-disable-javascript=true" + - "--chromium-allow-list=file:///tmp/.*" + tika: + image: ghcr.io/paperless-ngx/tika:latest + hostname: tika + container_name: tika + network_mode: host + restart: unless-stopped diff --git a/docker/compose/docker-compose.mariadb-tika.yml b/docker/compose/docker-compose.mariadb-tika.yml index b3699e4d7..4bbb390f0 100644 --- a/docker/compose/docker-compose.mariadb-tika.yml +++ b/docker/compose/docker-compose.mariadb-tika.yml @@ -77,8 +77,8 @@ services: PAPERLESS_REDIS: redis://broker:6379 PAPERLESS_DBENGINE: mariadb PAPERLESS_DBHOST: db - PAPERLESS_DBUSER: paperless - PAPERLESS_DBPASSWORD: paperless + PAPERLESS_DBUSER: paperless # only needed if non-default username + PAPERLESS_DBPASS: paperless # only needed if non-default password PAPERLESS_DBPORT: 3306 PAPERLESS_TIKA_ENABLED: 1 PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000 @@ -87,9 +87,12 @@ services: gotenberg: image: docker.io/gotenberg/gotenberg:7.6 restart: unless-stopped + # The gotenberg chromium route is used to convert .eml files. We do not + # want to allow external content like tracking pixels or even javascript. command: - "gotenberg" - - "--chromium-disable-routes=true" + - "--chromium-disable-javascript=true" + - "--chromium-allow-list=file:///tmp/.*" tika: image: ghcr.io/paperless-ngx/tika:latest diff --git a/docker/compose/docker-compose.mariadb.yml b/docker/compose/docker-compose.mariadb.yml index 8cb452464..a18e0fb3e 100644 --- a/docker/compose/docker-compose.mariadb.yml +++ b/docker/compose/docker-compose.mariadb.yml @@ -71,8 +71,8 @@ services: PAPERLESS_REDIS: redis://broker:6379 PAPERLESS_DBENGINE: mariadb PAPERLESS_DBHOST: db - PAPERLESS_DBUSER: paperless - PAPERLESS_DBPASSWORD: paperless + PAPERLESS_DBUSER: paperless # only needed if non-default username + PAPERLESS_DBPASS: paperless # only needed if non-default password PAPERLESS_DBPORT: 3306 diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml index c4333ad35..1158e7d67 100644 --- a/docker/compose/docker-compose.postgres-tika.yml +++ b/docker/compose/docker-compose.postgres-tika.yml @@ -79,9 +79,13 @@ services: gotenberg: image: docker.io/gotenberg/gotenberg:7.6 restart: unless-stopped + + # The gotenberg chromium route is used to convert .eml files. We do not + # want to allow external content like tracking pixels or even javascript. command: - "gotenberg" - - "--chromium-disable-routes=true" + - "--chromium-disable-javascript=true" + - "--chromium-allow-list=file:///tmp/.*" tika: image: ghcr.io/paperless-ngx/tika:latest diff --git a/docker/compose/docker-compose.sqlite-tika.yml b/docker/compose/docker-compose.sqlite-tika.yml index a7b9a4ebe..a331c1ad1 100644 --- a/docker/compose/docker-compose.sqlite-tika.yml +++ b/docker/compose/docker-compose.sqlite-tika.yml @@ -67,9 +67,13 @@ services: gotenberg: image: docker.io/gotenberg/gotenberg:7.6 restart: unless-stopped + + # The gotenberg chromium route is used to convert .eml files. We do not + # want to allow external content like tracking pixels or even javascript. command: - "gotenberg" - - "--chromium-disable-routes=true" + - "--chromium-disable-javascript=true" + - "--chromium-allow-list=file:///tmp/.*" tika: image: ghcr.io/paperless-ngx/tika:latest diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index d1107feca..74e080671 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -77,6 +77,46 @@ nltk_data () { } +custom_container_init() { + # Mostly borrowed from the LinuxServer.io base image + # https://github.com/linuxserver/docker-baseimage-ubuntu/tree/bionic/root/etc/cont-init.d + local -r custom_script_dir="/custom-cont-init.d" + # Tamper checking. + # Don't run files which are owned by anyone except root + # Don't run files which are writeable by others + if [ -d "${custom_script_dir}" ]; then + if [ -n "$(/usr/bin/find "${custom_script_dir}" -maxdepth 1 ! -user root)" ]; then + echo "**** Potential tampering with custom scripts detected ****" + echo "**** The folder '${custom_script_dir}' must be owned by root ****" + return 0 + fi + if [ -n "$(/usr/bin/find "${custom_script_dir}" -maxdepth 1 -perm -o+w)" ]; then + echo "**** The folder '${custom_script_dir}' or some of contents have write permissions for others, which is a security risk. ****" + echo "**** Please review the permissions and their contents to make sure they are owned by root, and can only be modified by root. ****" + return 0 + fi + + # Make sure custom init directory has files in it + if [ -n "$(/bin/ls -A "${custom_script_dir}" 2>/dev/null)" ]; then + echo "[custom-init] files found in ${custom_script_dir} executing" + # Loop over files in the directory + for SCRIPT in "${custom_script_dir}"/*; do + NAME="$(basename "${SCRIPT}")" + if [ -f "${SCRIPT}" ]; then + echo "[custom-init] ${NAME}: executing..." + /bin/bash "${SCRIPT}" + echo "[custom-init] ${NAME}: exited $?" + elif [ ! -f "${SCRIPT}" ]; then + echo "[custom-init] ${NAME}: is not a file" + fi + done + else + echo "[custom-init] no custom files found exiting..." + fi + + fi +} + initialize() { # Setup environment from secrets before anything else @@ -132,13 +172,16 @@ initialize() { set -e "${gosu_cmd[@]}" /sbin/docker-prepare.sh + + # Leave this last thing + custom_container_init + } install_languages() { echo "Installing languages..." - local -r langs="$1" - read -ra langs <<<"$langs" + read -ra langs <<<"$1" # Check that it is not empty if [ ${#langs[@]} -eq 0 ]; then diff --git a/docker/docker-prepare.sh b/docker/docker-prepare.sh index a73b5aad9..c3a01ec8d 100755 --- a/docker/docker-prepare.sh +++ b/docker/docker-prepare.sh @@ -89,46 +89,6 @@ superuser() { fi } -custom_container_init() { - # Mostly borrowed from the LinuxServer.io base image - # https://github.com/linuxserver/docker-baseimage-ubuntu/tree/bionic/root/etc/cont-init.d - local -r custom_script_dir="/custom-cont-init.d" - # Tamper checking. - # Don't run files which are owned by anyone except root - # Don't run files which are writeable by others - if [ -d "${custom_script_dir}" ]; then - if [ -n "$(/usr/bin/find "${custom_script_dir}" -maxdepth 1 ! -user root)" ]; then - echo "**** Potential tampering with custom scripts detected ****" - echo "**** The folder '${custom_script_dir}' must be owned by root ****" - return 0 - fi - if [ -n "$(/usr/bin/find "${custom_script_dir}" -maxdepth 1 -perm -o+w)" ]; then - echo "**** The folder '${custom_script_dir}' or some of contents have write permissions for others, which is a security risk. ****" - echo "**** Please review the permissions and their contents to make sure they are owned by root, and can only be modified by root. ****" - return 0 - fi - - # Make sure custom init directory has files in it - if [ -n "$(/bin/ls -A "${custom_script_dir}" 2>/dev/null)" ]; then - echo "[custom-init] files found in ${custom_script_dir} executing" - # Loop over files in the directory - for SCRIPT in "${custom_script_dir}"/*; do - NAME="$(basename "${SCRIPT}")" - if [ -f "${SCRIPT}" ]; then - echo "[custom-init] ${NAME}: executing..." - /bin/bash "${SCRIPT}" - echo "[custom-init] ${NAME}: exited $?" - elif [ ! -f "${SCRIPT}" ]; then - echo "[custom-init] ${NAME}: is not a file" - fi - done - else - echo "[custom-init] no custom files found exiting..." - fi - - fi -} - do_work() { if [[ "${PAPERLESS_DBENGINE}" == "mariadb" ]]; then wait_for_mariadb @@ -144,9 +104,6 @@ do_work() { superuser - # Leave this last thing - custom_container_init - } do_work diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 7890f9828..000000000 --- a/docs/Makefile +++ /dev/null @@ -1,181 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " livehtml to preview changes with live reload in your browser" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -livehtml: - sphinx-autobuild "./" "$(BUILDDIR)" $(O) - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/RIPEAtlasToolsMagellan.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/RIPEAtlasToolsMagellan.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/RIPEAtlasToolsMagellan" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/RIPEAtlasToolsMagellan" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css deleted file mode 100644 index c0b3ed83a..000000000 --- a/docs/_static/css/custom.css +++ /dev/null @@ -1,597 +0,0 @@ -/* Variables */ -:root { - --color-text-body: #5c5962; - --color-text-body-light: #fcfcfc; - --color-text-anchor: #7253ed; - --color-text-alt: rgba(0, 0, 0, 0.3); - --color-text-title: #27262b; - --color-text-code-inline: #e74c3c; - --color-text-code-nt: #062873; - --color-text-selection: #b19eff; - --color-bg-body: #fcfcfc; - --color-bg-body-alt: #f3f6f6; - --color-bg-side-nav: #f5f6fa; - --color-bg-side-nav-hover: #ebedf5; - --color-bg-code-block: var(--color-bg-side-nav); - --color-border: #eeebee; - --color-btn-neutral-bg: #f3f6f6; - --color-btn-neutral-bg-hover: #e5ebeb; - --color-success-title: #1abc9c; - --color-success-body: #dbfaf4; - --color-warning-title: #f0b37e; - --color-warning-body: #ffedcc; - --color-danger-title: #f29f97; - --color-danger-body: #fdf3f2; - --color-info-title: #6ab0de; - --color-info-body: #e7f2fa; -} - -.dark-mode { - --color-text-body: #abb2bf; - --color-text-body-light: #9499a2; - --color-text-alt: rgba(0255, 255, 255, 0.5); - --color-text-title: var(--color-text-anchor); - --color-text-code-inline: #abb2bf; - --color-text-code-nt: #2063f3; - --color-text-selection: #030303; - --color-bg-body: #1d1d20 !important; - --color-bg-body-alt: #131315; - --color-bg-side-nav: #18181a; - --color-bg-side-nav-hover: #101216; - --color-bg-code-block: #101216; - --color-border: #47494f; - --color-btn-neutral-bg: #242529; - --color-btn-neutral-bg-hover: #101216; - --color-success-title: #02120f; - --color-success-body: #041b17; - --color-warning-title: #1b0e03; - --color-warning-body: #371d06; - --color-danger-title: #120902; - --color-danger-body: #1b0503; - --color-info-title: #020608; - --color-info-body: #06141e; -} - -* { - transition: background-color 0.3s ease, border-color 0.3s ease; -} - -/* Typography */ -body { - font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif; - font-size: inherit; - line-height: 1.4; - color: var(--color-text-body); -} - -.rst-content p { - word-break: break-word; -} - -h1, h2, h3, h4, h5, h6 { - font-family: inherit; -} - -.rst-content .toctree-wrapper>p.caption, .rst-content h1, .rst-content h2, .rst-content h3, .rst-content h4, .rst-content h5, .rst-content h6 { - padding-top: .5em; -} - -p, .main-content-wrap, .rst-content .section ul, .rst-content .toctree-wrapper ul, .rst-content section ul, .wy-plain-list-disc, article ul { - line-height: 1.6; -} - -pre, .code, .rst-content .linenodiv pre, .rst-content div[class^=highlight] pre, .rst-content pre.literal-block { - font-family: "SFMono-Regular", Menlo,Consolas, Monospace; - font-size: 0.75em; - line-height: 1.8; -} - -.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4 { - font-size: 1rem -} - -.rst-versions { - font-family: inherit; - line-height: 1; -} - -footer, footer p { - font-size: .8rem; -} - -footer .rst-footer-buttons { - font-size: 1rem; -} - -@media (max-width: 400px) { - /* break code lines on mobile */ - pre, code { - word-break: break-word; - } -} - - -/* Layout */ -.wy-side-nav-search, .wy-menu-vertical { - width: auto; -} - -.wy-nav-side { - z-index: 0; - display: flex; - flex-wrap: wrap; - background-color: var(--color-bg-side-nav); -} - -.wy-side-scroll { - width: 100%; - overflow-y: auto; -} - -@media (min-width: 66.5rem) { - .wy-side-scroll { - width:264px - } -} - -@media (min-width: 50rem) { - .wy-nav-side { - flex-wrap: nowrap; - position: fixed; - width: 248px; - height: 100%; - flex-direction: column; - border-right: 1px solid var(--color-border); - align-items:flex-end - } -} - -@media (min-width: 66.5rem) { - .wy-nav-side { - width: calc((100% - 1064px) / 2 + 264px); - min-width:264px - } -} - -@media (min-width: 50rem) { - .wy-nav-content-wrap { - position: relative; - max-width: 800px; - margin-left:248px - } -} - -@media (min-width: 66.5rem) { - .wy-nav-content-wrap { - margin-left:calc((100% - 1064px) / 2 + 264px) - } -} - - -/* Colors */ -body.wy-body-for-nav, -.wy-nav-content { - background: var(--color-bg-body); -} - -.wy-nav-side { - border-right: 1px solid var(--color-border); -} - -.wy-side-nav-search, .wy-nav-top { - background: var(--color-bg-side-nav); - border-bottom: 1px solid var(--color-border); -} - -.wy-nav-content-wrap { - background: inherit; -} - -.wy-side-nav-search > a, .wy-nav-top a, .wy-nav-top i { - color: var(--color-text-title); -} - -.wy-side-nav-search > a:hover, .wy-nav-top a:hover { - background: transparent; -} - -.wy-side-nav-search > div.version { - color: var(--color-text-alt) -} - -.wy-side-nav-search > div[role="search"] { - border-top: 1px solid var(--color-border); -} - -.wy-menu-vertical li.toctree-l2.current>a, .wy-menu-vertical li.toctree-l2.current li.toctree-l3>a, -.wy-menu-vertical li.toctree-l3.current>a, .wy-menu-vertical li.toctree-l3.current li.toctree-l4>a { - background: var(--color-bg-side-nav); -} - -.rst-content .highlighted { - background: #eedd85; - box-shadow: 0 0 0 2px #eedd85; - font-weight: 600; -} - -.wy-side-nav-search input[type=text], -html.writer-html5 .rst-content table.docutils th { - color: var(--color-text-body); -} - -.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td, -.wy-table-backed, -.wy-table-odd td, -.wy-table-striped tr:nth-child(2n-1) td { - background-color: var(--color-bg-body-alt); -} - -.rst-content table.docutils, -.wy-table-bordered-all, -html.writer-html5 .rst-content table.docutils th, -.rst-content table.docutils td, -.wy-table-bordered-all td, -hr { - border-color: var(--color-border) !important; -} - -::selection { - background: var(--color-text-selection); -} - -/* Ridiculous rules are taken from sphinx_rtd */ -.rst-content .admonition-title, -.wy-alert-title { - color: var(--color-text-body-light); -} - -.rst-content .hint, -.rst-content .important, -.rst-content .tip, -.rst-content .wy-alert-success, -.wy-alert.wy-alert-success { - background: var(--color-success-body); -} - -.rst-content .hint .admonition-title, -.rst-content .hint .wy-alert-title, -.rst-content .important .admonition-title, -.rst-content .important .wy-alert-title, -.rst-content .tip .admonition-title, -.rst-content .tip .wy-alert-title, -.rst-content .wy-alert-success .admonition-title, -.rst-content .wy-alert-success .wy-alert-title, -.wy-alert.wy-alert-success .rst-content .admonition-title, -.wy-alert.wy-alert-success .wy-alert-title { - background-color: var(--color-success-title); -} - -.rst-content .admonition-todo, -.rst-content .attention, -.rst-content .caution, -.rst-content .warning, -.rst-content .wy-alert-warning, -.wy-alert.wy-alert-warning { - background: var(--color-warning-body); -} - -.rst-content .admonition-todo .admonition-title, -.rst-content .admonition-todo .wy-alert-title, -.rst-content .attention .admonition-title, -.rst-content .attention .wy-alert-title, -.rst-content .caution .admonition-title, -.rst-content .caution .wy-alert-title, -.rst-content .warning .admonition-title, -.rst-content .warning .wy-alert-title, -.rst-content .wy-alert-warning .admonition-title, -.rst-content .wy-alert-warning .wy-alert-title, -.rst-content .wy-alert.wy-alert-warning .admonition-title, -.wy-alert.wy-alert-warning .rst-content .admonition-title, -.wy-alert.wy-alert-warning .wy-alert-title { - background: var(--color-warning-title); -} - -.rst-content .danger, -.rst-content .error, -.rst-content .wy-alert-danger, -.wy-alert.wy-alert-danger { - background: var(--color-danger-body); -} - -.rst-content .danger .admonition-title, -.rst-content .danger .wy-alert-title, -.rst-content .error .admonition-title, -.rst-content .error .wy-alert-title, -.rst-content .wy-alert-danger .admonition-title, -.rst-content .wy-alert-danger .wy-alert-title, -.wy-alert.wy-alert-danger .rst-content .admonition-title, -.wy-alert.wy-alert-danger .wy-alert-title { - background: var(--color-danger-title); -} - -.rst-content .note, -.rst-content .seealso, -.rst-content .wy-alert-info, -.wy-alert.wy-alert-info { - background: var(--color-info-body); -} - -.rst-content .note .admonition-title, -.rst-content .note .wy-alert-title, -.rst-content .seealso .admonition-title, -.rst-content .seealso .wy-alert-title, -.rst-content .wy-alert-info .admonition-title, -.rst-content .wy-alert-info .wy-alert-title, -.wy-alert.wy-alert-info .rst-content .admonition-title, -.wy-alert.wy-alert-info .wy-alert-title { - background: var(--color-info-title); -} - - - -/* Links */ -a, a:visited, -.wy-menu-vertical a, -a.icon.icon-home, -.wy-menu-vertical li.toctree-l1.current > a.current { - color: var(--color-text-anchor); - text-decoration: none; -} - -a:hover, .wy-breadcrumbs-aside a { - color: var(--color-text-anchor); /* reset */ -} - -.rst-versions a, .rst-versions .rst-current-version { - color: #var(--color-text-anchor); -} - -.wy-nav-content a.reference, .wy-nav-content a:not([class]) { - background-image: linear-gradient(var(--color-border) 0%, var(--color-border) 100%); - background-repeat: repeat-x; - background-position: 0 100%; - background-size: 1px 1px; -} - -.wy-nav-content a.reference:hover, .wy-nav-content a:not([class]):hover { - background-image: linear-gradient(rgba(114,83,237,0.45) 0%, rgba(114,83,237,0.45) 100%); - background-size: 1px 1px; -} - -.wy-menu-vertical a:hover, -.wy-menu-vertical li.current a:hover, -.wy-menu-vertical a:active { - background: var(--color-bg-side-nav-hover) !important; - color: var(--color-text-body); -} - -.wy-menu-vertical li.toctree-l1.current>a, -.wy-menu-vertical li.current>a, -.wy-menu-vertical li.on a { - background-color: var(--color-bg-side-nav-hover); - border: none; - font-weight: normal; -} - -.wy-menu-vertical li.current { - background-color: inherit; -} - -.wy-menu-vertical li.current a { - border-right: none; -} - -.wy-menu-vertical li.toctree-l2 a, -.wy-menu-vertical li.toctree-l3 a, -.wy-menu-vertical li.toctree-l4 a, -.wy-menu-vertical li.toctree-l5 a, -.wy-menu-vertical li.toctree-l6 a, -.wy-menu-vertical li.toctree-l7 a, -.wy-menu-vertical li.toctree-l8 a, -.wy-menu-vertical li.toctree-l9 a, -.wy-menu-vertical li.toctree-l10 a { - color: var(--color-text-body); -} - -a.image-reference, a.image-reference:hover { - background: none !important; -} - -a.image-reference img { - cursor: zoom-in; -} - - -/* Code blocks */ -.rst-content code, .rst-content tt, code { - padding: 0.25em; - font-weight: 400; - background-color: var(--color-bg-code-block); - border: 1px solid var(--color-border); - border-radius: 4px; -} - -.rst-content div[class^=highlight], .rst-content pre.literal-block { - padding: 0.7rem; - margin-top: 0; - margin-bottom: 0.75rem; - overflow-x: auto; - background-color: var(--color-bg-side-nav); - border-color: var(--color-border); - border-radius: 4px; - box-shadow: none; -} - -.rst-content .admonition-title, -.rst-content div.admonition, -.wy-alert-title { - padding: 10px 12px; - border-top-left-radius: 4px; - border-top-right-radius: 4px; -} - -.highlight .go { - color: inherit; -} - -.highlight .nt { - color: var(--color-text-code-nt); -} - -.rst-content code.literal, -.rst-content tt.literal, -html.writer-html5 .rst-content dl.footnote code { - border-color: var(--color-border); - background-color: var(--color-border); - color: var(--color-text-code-inline) -} - - -/* Search */ -.wy-side-nav-search input[type=text] { - border: none; - border-radius: 0; - background-color: transparent; - font-family: inherit; - font-size: .85rem; - box-shadow: none; - padding: .7rem 1rem .7rem 2.8rem; - margin: 0; -} - -#rtd-search-form { - position: relative; -} - -#rtd-search-form:before { - font: normal normal normal 14px/1 FontAwesome; - font-size: inherit; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - content: "\f002"; - color: var(--color-text-alt); - position: absolute; - left: 1.5rem; - top: .7rem; -} - -/* Side nav */ -.wy-side-nav-search { - padding: 1rem 0 0 0; -} - -.wy-menu-vertical li a button.toctree-expand { - float: right; - margin-right: -1.5em; - padding: 0 .5em; -} - -.wy-menu-vertical a, -.wy-menu-vertical li.current>a, -.wy-menu-vertical li.current li>a { - padding-right: 1.5em !important; -} - -.wy-menu-vertical li.current li>a.current { - font-weight: 600; -} - -/* Misc spacing */ -.rst-content .admonition-title, .wy-alert-title { - padding: 10px 12px; -} - -/* Buttons */ -.btn { - display: inline-block; - box-sizing: border-box; - padding: 0.3em 1em; - margin: 0; - font-family: inherit; - font-size: inherit; - font-weight: 500; - line-height: 1.5; - color: #var(--color-text-anchor); - text-decoration: none; - vertical-align: baseline; - background-color: #f7f7f7; - border-width: 0; - border-radius: 4px; - box-shadow: 0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08); - appearance: none; -} - -.btn:active { - padding: 0.3em 1em; -} - -.rst-content .btn:focus { - outline: 1px solid #ccc; -} - -.rst-content .btn-neutral, .rst-content .btn span.fa { - color: var(--color-text-body) !important; -} - -.btn-neutral { - background-color: var(--color-btn-neutral-bg) !important; - color: var(--color-btn-neutral-text) !important; - border: 1px solid var(--color-btn-neutral-bg); -} - -.btn:hover, .btn-neutral:hover { - background-color: var(--color-btn-neutral-bg-hover) !important; -} - - -/* Icon overrides */ -.wy-side-nav-search a.icon-home:before { - display: none; -} - -.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before { - content: "\f106"; /* fa-angle-up */ -} - -.fa-plus-square-o:before, .wy-menu-vertical li button.toctree-expand:before { - content: "\f107"; /* fa-angle-down */ -} - - -/* Misc */ -.wy-nav-top { - line-height: 36px; -} - -.wy-nav-top > i { - font-size: 24px; - padding: 8px 0 0 2px; - color:#var(--color-text-anchor); -} - -.rst-content table.docutils td, -.rst-content table.docutils th, -.rst-content table.field-list td, -.rst-content table.field-list th, -.wy-table td, -.wy-table th { - padding: 8px 14px; -} - -.dark-mode-toggle { - position: absolute; - top: 14px; - right: 12px; - height: 20px; - width: 24px; - z-index: 10; - border: none; - background-color: transparent; - color: inherit; - opacity: 0.7; -} - -.wy-nav-content-wrap { - z-index: 20; -} diff --git a/docs/_static/js/darkmode.js b/docs/_static/js/darkmode.js deleted file mode 100644 index 909472587..000000000 --- a/docs/_static/js/darkmode.js +++ /dev/null @@ -1,47 +0,0 @@ -let toggleButton -let icon - -function load() { - 'use strict' - - toggleButton = document.createElement('button') - toggleButton.setAttribute('title', 'Toggle dark mode') - toggleButton.classList.add('dark-mode-toggle') - icon = document.createElement('i') - icon.classList.add('fa', darkModeState ? 'fa-sun-o' : 'fa-moon-o') - toggleButton.appendChild(icon) - document.body.prepend(toggleButton) - - // Listen for changes in the OS settings - // addListener is used because older versions of Safari don't support addEventListener - // prefersDarkQuery set in - if (prefersDarkQuery) { - prefersDarkQuery.addListener(function (evt) { - toggleDarkMode(evt.matches) - }) - } - - // Initial setting depending on the prefers-color-mode or localstorage - // darkModeState should be set in the document to prevent flash - if (darkModeState == undefined) darkModeState = false - toggleDarkMode(darkModeState) - - // Toggles the "dark-mode" class on click and sets localStorage state - toggleButton.addEventListener('click', () => { - darkModeState = !darkModeState - - toggleDarkMode(darkModeState) - localStorage.setItem('dark-mode', darkModeState) - }) -} - -function toggleDarkMode(state) { - document.documentElement.classList.toggle('dark-mode', state) - document.documentElement.classList.toggle('light-mode', !state) - icon.classList.remove('fa-sun-o') - icon.classList.remove('fa-moon-o') - icon.classList.add(state ? 'fa-sun-o' : 'fa-moon-o') - darkModeState = state -} - -document.addEventListener('DOMContentLoaded', load) diff --git a/docs/_static/screenshots/mail-rules-edited.png b/docs/_static/screenshots/mail-rules-edited.png deleted file mode 100644 index 68a170ac3c72dfd953fc0fd9475443ca77454f69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98619 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 cY5r%0j)V(;C5-ZzrGp diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html deleted file mode 100644 index cf648b606..000000000 --- a/docs/_templates/layout.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "!layout.html" %} -{% block extrahead %} - - {{ super() }} -{% endblock %} diff --git a/docs/administration.md b/docs/administration.md new file mode 100644 index 000000000..a8009c85e --- /dev/null +++ b/docs/administration.md @@ -0,0 +1,502 @@ +# Administration + +## Making backups {#backup} + +Multiple options exist for making backups of your paperless instance, +depending on how you installed paperless. + +Before making backups, make sure that paperless is not running. + +Options available to any installation of paperless: + +- Use the [document exporter](administration#exporter). The document exporter exports all your documents, + thumbnails and metadata to a specific folder. You may import your + documents into a fresh instance of paperless again or store your + documents in another DMS with this export. +- The document exporter is also able to update an already existing + export. Therefore, incremental backups with `rsync` are entirely + possible. + +!!! caution + + You cannot import the export generated with one version of paperless in + a different version of paperless. The export contains an exact image of + the database, and migrations may change the database layout. + +Options available to docker installations: + +- Backup the docker volumes. These usually reside within + `/var/lib/docker/volumes` on the host and you need to be root in + order to access them. + + Paperless uses 4 volumes: + + - `paperless_media`: This is where your documents are stored. + - `paperless_data`: This is where auxillary data is stored. This + folder also contains the SQLite database, if you use it. + - `paperless_pgdata`: Exists only if you use PostgreSQL and + contains the database. + - `paperless_dbdata`: Exists only if you use MariaDB and contains + the database. + +Options available to bare-metal and non-docker installations: + +- Backup the entire paperless folder. This ensures that if your + paperless instance crashes at some point or your disk fails, you can + simply copy the folder back into place and it works. + + When using PostgreSQL or MariaDB, you'll also have to backup the + database. + +### Restoring {#migrating-restoring} + +## Updating Paperless {#updating} + +### Docker Route + +If a new release of paperless-ngx is available, upgrading depends on how +you installed paperless-ngx in the first place. The releases are +available at the [release +page](https://github.com/paperless-ngx/paperless-ngx/releases). + +First of all, ensure that paperless is stopped. + +```shell-session +$ cd /path/to/paperless +$ docker-compose down +``` + +After that, [make a backup](#backup). + +A. If you pull the image from the docker hub, all you need to do is: + + ``` shell-session + $ docker-compose pull + $ docker-compose up + ``` + + The docker-compose files refer to the `latest` version, which is + always the latest stable release. + +B. If you built the image yourself, do the following: + + ``` shell-session + $ git pull + $ docker-compose build + $ docker-compose up + ``` + +Running `docker-compose up` will also apply any new database migrations. +If you see everything working, press CTRL+C once to gracefully stop +paperless. Then you can start paperless-ngx with `-d` to have it run in +the background. + +!!! note + + In version 0.9.14, the update process was changed. In 0.9.13 and + earlier, the docker-compose files specified exact versions and pull + won't automatically update to newer versions. In order to enable + updates as described above, either get the new `docker-compose.yml` + file from + [here](https://github.com/paperless-ngx/paperless-ngx/tree/master/docker/compose) + or edit the `docker-compose.yml` file, find the line that says + + ``` + image: ghcr.io/paperless-ngx/paperless-ngx:0.9.x + ``` + + and replace the version with `latest`: + + ``` + image: ghcr.io/paperless-ngx/paperless-ngx:latest + ``` + +!!! note + + In version 1.7.1 and onwards, the Docker image can now be pinned to a + release series. This is often combined with automatic updaters such as + Watchtower to allow safer unattended upgrading to new bugfix releases + only. It is still recommended to always review release notes before + upgrading. To pin your install to a release series, edit the + `docker-compose.yml` find the line that says + + ``` + image: ghcr.io/paperless-ngx/paperless-ngx:latest + ``` + + and replace the version with the series you want to track, for + example: + + ``` + image: ghcr.io/paperless-ngx/paperless-ngx:1.7 + ``` + +### Bare Metal Route + +After grabbing the new release and unpacking the contents, do the +following: + +1. Update dependencies. New paperless version may require additional + dependencies. The dependencies required are listed in the section + about + [bare metal installations](/setup#bare_metal). + +2. Update python requirements. Keep in mind to activate your virtual + environment before that, if you use one. + + ```shell-session + $ pip install -r requirements.txt + ``` + +3. Migrate the database. + + ```shell-session + $ cd src + $ python3 manage.py migrate + ``` + + This might not actually do anything. Not every new paperless version + comes with new database migrations. + +## Downgrading Paperless + +Downgrades are possible. However, some updates also contain database +migrations (these change the layout of the database and may move data). +In order to move back from a version that applied database migrations, +you'll have to revert the database migration _before_ downgrading, and +then downgrade paperless. + +This table lists the compatible versions for each database migration +number. + +| Migration number | Version range | +| ---------------- | --------------- | +| 1011 | 1.0.0 | +| 1012 | 1.1.0 - 1.2.1 | +| 1014 | 1.3.0 - 1.3.1 | +| 1016 | 1.3.2 - current | + +Execute the following management command to migrate your database: + +```shell-session +$ python3 manage.py migrate documents +``` + +!!! note + + Some migrations cannot be undone. The command will issue errors if that + happens. + +## Management utilities {#management-commands} + +Paperless comes with some management commands that perform various +maintenance tasks on your paperless instance. You can invoke these +commands in the following way: + +With docker-compose, while paperless is running: + +```shell-session +$ cd /path/to/paperless +$ docker-compose exec webserver +``` + +With docker, while paperless is running: + +```shell-session +$ docker exec -it +``` + +Bare metal: + +```shell-session +$ cd /path/to/paperless/src +$ python3 manage.py +``` + +All commands have built-in help, which can be accessed by executing them +with the argument `--help`. + +### Document exporter {#exporter} + +The document exporter exports all your data from paperless into a folder +for backup or migration to another DMS. + +If you use the document exporter within a cronjob to backup your data +you might use the `-T` flag behind exec to suppress "The input device +is not a TTY" errors. For example: +`docker-compose exec -T webserver document_exporter ../export` + +``` +document_exporter target [-c] [-f] [-d] + +optional arguments: +-c, --compare-checksums +-f, --use-filename-format +-d, --delete +``` + +`target` is a folder to which the data gets written. This includes +documents, thumbnails and a `manifest.json` file. The manifest contains +all metadata from the database (correspondents, tags, etc). + +When you use the provided docker compose script, specify `../export` as +the target. This path inside the container is automatically mounted on +your host on the folder `export`. + +If the target directory already exists and contains files, paperless +will assume that the contents of the export directory are a previous +export and will attempt to update the previous export. Paperless will +only export changed and added files. Paperless determines whether a file +has changed by inspecting the file attributes "date/time modified" and +"size". If that does not work out for you, specify +`--compare-checksums` and paperless will attempt to compare file +checksums instead. This is slower. + +Paperless will not remove any existing files in the export directory. If +you want paperless to also remove files that do not belong to the +current export such as files from deleted documents, specify `--delete`. +Be careful when pointing paperless to a directory that already contains +other files. + +The filenames generated by this command follow the format +`[date created] [correspondent] [title].[extension]`. If you want +paperless to use `PAPERLESS_FILENAME_FORMAT` for exported filenames +instead, specify `--use-filename-format`. + +### Document importer {#importer} + +The document importer takes the export produced by the [Document +exporter](#document-exporter) and imports it into paperless. + +The importer works just like the exporter. You point it at a directory, +and the script does the rest of the work: + +``` +document_importer source +``` + +When you use the provided docker compose script, put the export inside +the `export` folder in your paperless source directory. Specify +`../export` as the `source`. + +!!! note + + Importing from a previous version of Paperless may work, but for best + results it is suggested to match the versions. + +### Document retagger {#retagger} + +Say you've imported a few hundred documents and now want to introduce a +tag or set up a new correspondent, and apply its matching to all of the +currently-imported docs. This problem is common enough that there are +tools for it. + +``` +document_retagger [-h] [-c] [-T] [-t] [-i] [--use-first] [-f] + +optional arguments: +-c, --correspondent +-T, --tags +-t, --document_type +-s, --storage_path +-i, --inbox-only +--use-first +-f, --overwrite +``` + +Run this after changing or adding matching rules. It'll loop over all +of the documents in your database and attempt to match documents +according to the new rules. + +Specify any combination of `-c`, `-T`, `-t` and `-s` to have the +retagger perform matching of the specified metadata type. If you don't +specify any of these options, the document retagger won't do anything. + +Specify `-i` to have the document retagger work on documents tagged with +inbox tags only. This is useful when you don't want to mess with your +already processed documents. + +When multiple document types or correspondents match a single document, +the retagger won't assign these to the document. Specify `--use-first` +to override this behavior and just use the first correspondent or type +it finds. This option does not apply to tags, since any amount of tags +can be applied to a document. + +Finally, `-f` specifies that you wish to overwrite already assigned +correspondents, types and/or tags. The default behavior is to not assign +correspondents and types to documents that have this data already +assigned. `-f` works differently for tags: By default, only additional +tags get added to documents, no tags will be removed. With `-f`, tags +that don't match a document anymore get removed as well. + +### Managing the Automatic matching algorithm + +The _Auto_ matching algorithm requires a trained neural network to work. +This network needs to be updated whenever somethings in your data +changes. The docker image takes care of that automatically with the task +scheduler. You can manually renew the classifier by invoking the +following management command: + +``` +document_create_classifier +``` + +This command takes no arguments. + +### Managing the document search index {#index} + +The document search index is responsible for delivering search results +for the website. The document index is automatically updated whenever +documents get added to, changed, or removed from paperless. However, if +the search yields non-existing documents or won't find anything, you +may need to recreate the index manually. + +``` +document_index {reindex,optimize} +``` + +Specify `reindex` to have the index created from scratch. This may take +some time. + +Specify `optimize` to optimize the index. This updates certain aspects +of the index and usually makes queries faster and also ensures that the +autocompletion works properly. This command is regularly invoked by the +task scheduler. + +### Managing filenames {#renamer} + +If you use paperless' feature to +[assign custom filenames to your documents](/advanced_usage#file_name_handling), you can use this command to move all your files after +changing the naming scheme. + +!!! warning + + Since this command moves your documents, it is advised to do a backup + beforehand. The renaming logic is robust and will never overwrite or + delete a file, but you can't ever be careful enough. + +``` +document_renamer +``` + +The command takes no arguments and processes all your documents at once. + +Learn how to use +[Management Utilities](#management-commands). + +### Sanity checker {#sanity-checker} + +Paperless has a built-in sanity checker that inspects your document +collection for issues. + +The issues detected by the sanity checker are as follows: + +- Missing original files. +- Missing archive files. +- Inaccessible original files due to improper permissions. +- Inaccessible archive files due to improper permissions. +- Corrupted original documents by comparing their checksum against + what is stored in the database. +- Corrupted archive documents by comparing their checksum against what + is stored in the database. +- Missing thumbnails. +- Inaccessible thumbnails due to improper permissions. +- Documents without any content (warning). +- Orphaned files in the media directory (warning). These are files + that are not referenced by any document im paperless. + +``` +document_sanity_checker +``` + +The command takes no arguments. Depending on the size of your document +archive, this may take some time. + +### Fetching e-mail + +Paperless automatically fetches your e-mail every 10 minutes by default. +If you want to invoke the email consumer manually, call the following +management command: + +``` +mail_fetcher +``` + +The command takes no arguments and processes all your mail accounts and +rules. + +!!! note + + As of October 2022 Microsoft no longer supports IMAP authentication + for Exchange servers, thus Exchange is no longer supported until a + solution is implemented in the Python IMAP library used by Paperless. + See + +[learn.microsoft.com](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online) + +### Creating archived documents {#archiver} + +Paperless stores archived PDF/A documents alongside your original +documents. These archived documents will also contain selectable text +for image-only originals. These documents are derived from the +originals, which are always stored unmodified. If coming from an earlier +version of paperless, your documents won't have archived versions. + +This command creates PDF/A documents for your documents. + +``` +document_archiver --overwrite --document +``` + +This command will only attempt to create archived documents when no +archived document exists yet, unless `--overwrite` is specified. If +`--document ` is specified, the archiver will only process that +document. + +!!! note + + This command essentially performs OCR on all your documents again, + according to your settings. If you run this with + `PAPERLESS_OCR_MODE=redo`, it will potentially run for a very long time. + You can cancel the command at any time, since this command will skip + already archived versions the next time it is run. + +!!! note + + Some documents will cause errors and cannot be converted into PDF/A + documents, such as encrypted PDF documents. The archiver will skip over + these documents each time it sees them. + +### Managing encryption {#encyption} + +Documents can be stored in Paperless using GnuPG encryption. + +!!! warning + + Encryption is deprecated since paperless-ngx 0.9 and doesn't really + provide any additional security, since you have to store the passphrase + in a configuration file on the same system as the encrypted documents + for paperless to work. Furthermore, the entire text content of the + documents is stored plain in the database, even if your documents are + encrypted. Filenames are not encrypted as well. + + Also, the web server provides transparent access to your encrypted + documents. + + Consider running paperless on an encrypted filesystem instead, which + will then at least provide security against physical hardware theft. + +#### Enabling encryption + +Enabling encryption is no longer supported. + +#### Disabling encryption + +Basic usage to disable encryption of your document store: + +(Note: If `PAPERLESS_PASSPHRASE` isn't set already, you need to specify +it here) + +``` +decrypt_documents [--passphrase SECR3TP4SSPHRA$E] +``` diff --git a/docs/administration.rst b/docs/administration.rst deleted file mode 100644 index ed2075a48..000000000 --- a/docs/administration.rst +++ /dev/null @@ -1,523 +0,0 @@ - -************** -Administration -************** - -.. _administration-backup: - -Making backups -############## - -Multiple options exist for making backups of your paperless instance, -depending on how you installed paperless. - -Before making backups, make sure that paperless is not running. - -Options available to any installation of paperless: - -* Use the :ref:`document exporter `. - The document exporter exports all your documents, thumbnails and - metadata to a specific folder. You may import your documents into a - fresh instance of paperless again or store your documents in another - DMS with this export. -* The document exporter is also able to update an already existing export. - Therefore, incremental backups with ``rsync`` are entirely possible. - -.. caution:: - - You cannot import the export generated with one version of paperless in a - different version of paperless. The export contains an exact image of the - database, and migrations may change the database layout. - -Options available to docker installations: - -* Backup the docker volumes. These usually reside within - ``/var/lib/docker/volumes`` on the host and you need to be root in order - to access them. - - Paperless uses 4 volumes: - - * ``paperless_media``: This is where your documents are stored. - * ``paperless_data``: This is where auxillary data is stored. This - folder also contains the SQLite database, if you use it. - * ``paperless_pgdata``: Exists only if you use PostgreSQL and contains - the database. - * ``paperless_dbdata``: Exists only if you use MariaDB and contains - the database. - -Options available to bare-metal and non-docker installations: - -* Backup the entire paperless folder. This ensures that if your paperless instance - crashes at some point or your disk fails, you can simply copy the folder back - into place and it works. - - When using PostgreSQL or MariaDB, you'll also have to backup the database. - -.. _migrating-restoring: - -Restoring -========= - -.. _administration-updating: - -Updating Paperless -################## - -Docker Route -============ - -If a new release of paperless-ngx is available, upgrading depends on how you -installed paperless-ngx in the first place. The releases are available at the -`release page `_. - -First of all, ensure that paperless is stopped. - -.. code:: shell-session - - $ cd /path/to/paperless - $ docker-compose down - -After that, :ref:`make a backup `. - -A. If you pull the image from the docker hub, all you need to do is: - - .. code:: shell-session - - $ docker-compose pull - $ docker-compose up - - The docker-compose files refer to the ``latest`` version, which is always the latest - stable release. - -B. If you built the image yourself, do the following: - - .. code:: shell-session - - $ git pull - $ docker-compose build - $ docker-compose up - -Running ``docker-compose up`` will also apply any new database migrations. -If you see everything working, press CTRL+C once to gracefully stop paperless. -Then you can start paperless-ngx with ``-d`` to have it run in the background. - - .. note:: - - In version 0.9.14, the update process was changed. In 0.9.13 and earlier, the - docker-compose files specified exact versions and pull won't automatically - update to newer versions. In order to enable updates as described above, either - get the new ``docker-compose.yml`` file from `here `_ - or edit the ``docker-compose.yml`` file, find the line that says - - .. code:: - - image: ghcr.io/paperless-ngx/paperless-ngx:0.9.x - - and replace the version with ``latest``: - - .. code:: - - image: ghcr.io/paperless-ngx/paperless-ngx:latest - - .. note:: - In version 1.7.1 and onwards, the Docker image can now be pinned to a release series. - This is often combined with automatic updaters such as Watchtower to allow safer - unattended upgrading to new bugfix releases only. It is still recommended to always - review release notes before upgrading. To pin your install to a release series, edit - the ``docker-compose.yml`` find the line that says - - .. code:: - - image: ghcr.io/paperless-ngx/paperless-ngx:latest - - and replace the version with the series you want to track, for example: - - .. code:: - - image: ghcr.io/paperless-ngx/paperless-ngx:1.7 - -Bare Metal Route -================ - -After grabbing the new release and unpacking the contents, do the following: - -1. Update dependencies. New paperless version may require additional - dependencies. The dependencies required are listed in the section about - :ref:`bare metal installations `. - -2. Update python requirements. Keep in mind to activate your virtual environment - before that, if you use one. - - .. code:: shell-session - - $ pip install -r requirements.txt - -3. Migrate the database. - - .. code:: shell-session - - $ cd src - $ python3 manage.py migrate - - This might not actually do anything. Not every new paperless version comes with new - database migrations. - -Downgrading Paperless -##################### - -Downgrades are possible. However, some updates also contain database migrations (these change the layout of the database and may move data). -In order to move back from a version that applied database migrations, you'll have to revert the database migration *before* downgrading, -and then downgrade paperless. - -This table lists the compatible versions for each database migration number. - -+------------------+-----------------+ -| Migration number | Version range | -+------------------+-----------------+ -| 1011 | 1.0.0 | -+------------------+-----------------+ -| 1012 | 1.1.0 - 1.2.1 | -+------------------+-----------------+ -| 1014 | 1.3.0 - 1.3.1 | -+------------------+-----------------+ -| 1016 | 1.3.2 - current | -+------------------+-----------------+ - -Execute the following management command to migrate your database: - -.. code:: shell-session - - $ python3 manage.py migrate documents - -.. note:: - - Some migrations cannot be undone. The command will issue errors if that happens. - -.. _utilities-management-commands: - -Management utilities -#################### - -Paperless comes with some management commands that perform various maintenance -tasks on your paperless instance. You can invoke these commands in the following way: - -With docker-compose, while paperless is running: - -.. code:: shell-session - - $ cd /path/to/paperless - $ docker-compose exec webserver - -With docker, while paperless is running: - -.. code:: shell-session - - $ docker exec -it - -Bare metal: - -.. code:: shell-session - - $ cd /path/to/paperless/src - $ python3 manage.py - -All commands have built-in help, which can be accessed by executing them with -the argument ``--help``. - -.. _utilities-exporter: - -Document exporter -================= - -The document exporter exports all your data from paperless into a folder for -backup or migration to another DMS. - -If you use the document exporter within a cronjob to backup your data you might use the ``-T`` flag behind exec to suppress "The input device is not a TTY" errors. For example: ``docker-compose exec -T webserver document_exporter ../export`` - -.. code:: - - document_exporter target [-c] [-f] [-d] - - optional arguments: - -c, --compare-checksums - -f, --use-filename-format - -d, --delete - -``target`` is a folder to which the data gets written. This includes documents, -thumbnails and a ``manifest.json`` file. The manifest contains all metadata from -the database (correspondents, tags, etc). - -When you use the provided docker compose script, specify ``../export`` as the -target. This path inside the container is automatically mounted on your host on -the folder ``export``. - -If the target directory already exists and contains files, paperless will assume -that the contents of the export directory are a previous export and will attempt -to update the previous export. Paperless will only export changed and added files. -Paperless determines whether a file has changed by inspecting the file attributes -"date/time modified" and "size". If that does not work out for you, specify -``--compare-checksums`` and paperless will attempt to compare file checksums instead. -This is slower. - -Paperless will not remove any existing files in the export directory. If you want -paperless to also remove files that do not belong to the current export such as files -from deleted documents, specify ``--delete``. Be careful when pointing paperless to -a directory that already contains other files. - -The filenames generated by this command follow the format -``[date created] [correspondent] [title].[extension]``. -If you want paperless to use ``PAPERLESS_FILENAME_FORMAT`` for exported filenames -instead, specify ``--use-filename-format``. - - -.. _utilities-importer: - -Document importer -================= - -The document importer takes the export produced by the `Document exporter`_ and -imports it into paperless. - -The importer works just like the exporter. You point it at a directory, and -the script does the rest of the work: - -.. code:: - - document_importer source - -When you use the provided docker compose script, put the export inside the -``export`` folder in your paperless source directory. Specify ``../export`` -as the ``source``. - -.. note:: - - Importing from a previous version of Paperless may work, but for best results - it is suggested to match the versions. - -.. _utilities-retagger: - -Document retagger -================= - -Say you've imported a few hundred documents and now want to introduce -a tag or set up a new correspondent, and apply its matching to all of -the currently-imported docs. This problem is common enough that -there are tools for it. - -.. code:: - - document_retagger [-h] [-c] [-T] [-t] [-i] [--use-first] [-f] - - optional arguments: - -c, --correspondent - -T, --tags - -t, --document_type - -s, --storage_path - -i, --inbox-only - --use-first - -f, --overwrite - -Run this after changing or adding matching rules. It'll loop over all -of the documents in your database and attempt to match documents -according to the new rules. - -Specify any combination of ``-c``, ``-T``, ``-t`` and ``-s`` to have the -retagger perform matching of the specified metadata type. If you don't -specify any of these options, the document retagger won't do anything. - -Specify ``-i`` to have the document retagger work on documents tagged -with inbox tags only. This is useful when you don't want to mess with -your already processed documents. - -When multiple document types or correspondents match a single document, -the retagger won't assign these to the document. Specify ``--use-first`` -to override this behavior and just use the first correspondent or type -it finds. This option does not apply to tags, since any amount of tags -can be applied to a document. - -Finally, ``-f`` specifies that you wish to overwrite already assigned -correspondents, types and/or tags. The default behavior is to not -assign correspondents and types to documents that have this data already -assigned. ``-f`` works differently for tags: By default, only additional tags get -added to documents, no tags will be removed. With ``-f``, tags that don't -match a document anymore get removed as well. - - -Managing the Automatic matching algorithm -========================================= - -The *Auto* matching algorithm requires a trained neural network to work. -This network needs to be updated whenever somethings in your data -changes. The docker image takes care of that automatically with the task -scheduler. You can manually renew the classifier by invoking the following -management command: - -.. code:: - - document_create_classifier - -This command takes no arguments. - -.. _`administration-index`: - -Managing the document search index -================================== - -The document search index is responsible for delivering search results for the -website. The document index is automatically updated whenever documents get -added to, changed, or removed from paperless. However, if the search yields -non-existing documents or won't find anything, you may need to recreate the -index manually. - -.. code:: - - document_index {reindex,optimize} - -Specify ``reindex`` to have the index created from scratch. This may take some -time. - -Specify ``optimize`` to optimize the index. This updates certain aspects of -the index and usually makes queries faster and also ensures that the -autocompletion works properly. This command is regularly invoked by the task -scheduler. - -.. _utilities-renamer: - -Managing filenames -================== - -If you use paperless' feature to -:ref:`assign custom filenames to your documents `, -you can use this command to move all your files after changing -the naming scheme. - -.. warning:: - - Since this command moves your documents, it is advised to do - a backup beforehand. The renaming logic is robust and will never overwrite - or delete a file, but you can't ever be careful enough. - -.. code:: - - document_renamer - -The command takes no arguments and processes all your documents at once. - -Learn how to use :ref:`Management Utilities`. - - -.. _utilities-sanity-checker: - -Sanity checker -============== - -Paperless has a built-in sanity checker that inspects your document collection for issues. - -The issues detected by the sanity checker are as follows: - -* Missing original files. -* Missing archive files. -* Inaccessible original files due to improper permissions. -* Inaccessible archive files due to improper permissions. -* Corrupted original documents by comparing their checksum against what is stored in the database. -* Corrupted archive documents by comparing their checksum against what is stored in the database. -* Missing thumbnails. -* Inaccessible thumbnails due to improper permissions. -* Documents without any content (warning). -* Orphaned files in the media directory (warning). These are files that are not referenced by any document im paperless. - - -.. code:: - - document_sanity_checker - -The command takes no arguments. Depending on the size of your document archive, this may take some time. - - -Fetching e-mail -=============== - -Paperless automatically fetches your e-mail every 10 minutes by default. If -you want to invoke the email consumer manually, call the following management -command: - -.. code:: - - mail_fetcher - -The command takes no arguments and processes all your mail accounts and rules. - -.. _utilities-archiver: - -Creating archived documents -=========================== - -Paperless stores archived PDF/A documents alongside your original documents. -These archived documents will also contain selectable text for image-only -originals. -These documents are derived from the originals, which are always stored -unmodified. If coming from an earlier version of paperless, your documents -won't have archived versions. - -This command creates PDF/A documents for your documents. - -.. code:: - - document_archiver --overwrite --document - -This command will only attempt to create archived documents when no archived -document exists yet, unless ``--overwrite`` is specified. If ``--document `` -is specified, the archiver will only process that document. - -.. note:: - - This command essentially performs OCR on all your documents again, - according to your settings. If you run this with ``PAPERLESS_OCR_MODE=redo``, - it will potentially run for a very long time. You can cancel the command - at any time, since this command will skip already archived versions the next time - it is run. - -.. note:: - - Some documents will cause errors and cannot be converted into PDF/A documents, - such as encrypted PDF documents. The archiver will skip over these documents - each time it sees them. - -.. _utilities-encyption: - -Managing encryption -=================== - -Documents can be stored in Paperless using GnuPG encryption. - -.. danger:: - - Encryption is deprecated since paperless-ngx 0.9 and doesn't really provide any - additional security, since you have to store the passphrase in a configuration - file on the same system as the encrypted documents for paperless to work. - Furthermore, the entire text content of the documents is stored plain in the - database, even if your documents are encrypted. Filenames are not encrypted as - well. - - Also, the web server provides transparent access to your encrypted documents. - - Consider running paperless on an encrypted filesystem instead, which will then - at least provide security against physical hardware theft. - - -Enabling encryption -------------------- - -Enabling encryption is no longer supported. - - -Disabling encryption --------------------- - -Basic usage to disable encryption of your document store: - -(Note: If ``PAPERLESS_PASSPHRASE`` isn't set already, you need to specify it here) - -.. code:: - - decrypt_documents [--passphrase SECR3TP4SSPHRA$E] diff --git a/docs/advanced_usage.md b/docs/advanced_usage.md new file mode 100644 index 000000000..cdc8aa719 --- /dev/null +++ b/docs/advanced_usage.md @@ -0,0 +1,468 @@ +# Advanced Topics + +Paperless offers a couple features that automate certain tasks and make +your life easier. + +## Matching tags, correspondents, document types, and storage paths {#matching} + +Paperless will compare the matching algorithms defined by every tag, +correspondent, document type, and storage path in your database to see +if they apply to the text in a document. In other words, if you define a +tag called `Home Utility` that had a `match` property of `bc hydro` and +a `matching_algorithm` of `literal`, Paperless will automatically tag +your newly-consumed document with your `Home Utility` tag so long as the +text `bc hydro` appears in the body of the document somewhere. + +The matching logic is quite powerful. It supports searching the text of +your document with different algorithms, and as such, some +experimentation may be necessary to get things right. + +In order to have a tag, correspondent, document type, or storage path +assigned automatically to newly consumed documents, assign a match and +matching algorithm using the web interface. These settings define when +to assign tags, correspondents, document types, and storage paths to +documents. + +The following algorithms are available: + +- **Any:** Looks for any occurrence of any word provided in match in + the PDF. If you define the match as `Bank1 Bank2`, it will match + documents containing either of these terms. +- **All:** Requires that every word provided appears in the PDF, + albeit not in the order provided. +- **Literal:** Matches only if the match appears exactly as provided + (i.e. preserve ordering) in the PDF. +- **Regular expression:** Parses the match as a regular expression and + tries to find a match within the document. +- **Fuzzy match:** I don't know. Look at the source. +- **Auto:** Tries to automatically match new documents. This does not + require you to set a match. See the notes below. + +When using the _any_ or _all_ matching algorithms, you can search for +terms that consist of multiple words by enclosing them in double quotes. +For example, defining a match text of `"Bank of America" BofA` using the +_any_ algorithm, will match documents that contain either "Bank of +America" or "BofA", but will not match documents containing "Bank of +South America". + +Then just save your tag, correspondent, document type, or storage path +and run another document through the consumer. Once complete, you should +see the newly-created document, automatically tagged with the +appropriate data. + +### Automatic matching {#automatic_matching} + +Paperless-ngx comes with a new matching algorithm called _Auto_. This +matching algorithm tries to assign tags, correspondents, document types, +and storage paths to your documents based on how you have already +assigned these on existing documents. It uses a neural network under the +hood. + +If, for example, all your bank statements of your account 123 at the +Bank of America are tagged with the tag "bofa*123" and the matching +algorithm of this tag is set to \_Auto*, this neural network will examine +your documents and automatically learn when to assign this tag. + +Paperless tries to hide much of the involved complexity with this +approach. However, there are a couple caveats you need to keep in mind +when using this feature: + +- Changes to your documents are not immediately reflected by the + matching algorithm. The neural network needs to be _trained_ on your + documents after changes. Paperless periodically (default: once each + hour) checks for changes and does this automatically for you. +- The Auto matching algorithm only takes documents into account which + are NOT placed in your inbox (i.e. have any inbox tags assigned to + them). This ensures that the neural network only learns from + documents which you have correctly tagged before. +- The matching algorithm can only work if there is a correlation + between the tag, correspondent, document type, or storage path and + the document itself. Your bank statements usually contain your bank + account number and the name of the bank, so this works reasonably + well, However, tags such as "TODO" cannot be automatically + assigned. +- The matching algorithm needs a reasonable number of documents to + identify when to assign tags, correspondents, storage paths, and + types. If one out of a thousand documents has the correspondent + "Very obscure web shop I bought something five years ago", it will + probably not assign this correspondent automatically if you buy + something from them again. The more documents, the better. +- Paperless also needs a reasonable amount of negative examples to + decide when not to assign a certain tag, correspondent, document + type, or storage path. This will usually be the case as you start + filling up paperless with documents. Example: If all your documents + are either from "Webshop" and "Bank", paperless will assign one + of these correspondents to ANY new document, if both are set to + automatic matching. + +## Hooking into the consumption process + +Sometimes you may want to do something arbitrary whenever a document is +consumed. Rather than try to predict what you may want to do, Paperless +lets you execute scripts of your own choosing just before or after a +document is consumed using a couple simple hooks. + +Just write a script, put it somewhere that Paperless can read & execute, +and then put the path to that script in `paperless.conf` or +`docker-compose.env` with the variable name of either +`PAPERLESS_PRE_CONSUME_SCRIPT` or `PAPERLESS_POST_CONSUME_SCRIPT`. + +!!! info + + These scripts are executed in a **blocking** process, which means that + if a script takes a long time to run, it can significantly slow down + your document consumption flow. If you want things to run + asynchronously, you'll have to fork the process in your script and + exit. + +### Pre-consumption script + +Executed after the consumer sees a new document in the consumption +folder, but before any processing of the document is performed. This +script can access the following relevant environment variables set: + +- `DOCUMENT_SOURCE_PATH` + +A simple but common example for this would be creating a simple script +like this: + +`/usr/local/bin/ocr-pdf` + +```bash +#!/usr/bin/env bash +pdf2pdfocr.py -i ${DOCUMENT_SOURCE_PATH} +``` + +`/etc/paperless.conf` + +```bash +... +PAPERLESS_PRE_CONSUME_SCRIPT="/usr/local/bin/ocr-pdf" +... +``` + +This will pass the path to the document about to be consumed to +`/usr/local/bin/ocr-pdf`, which will in turn call +[pdf2pdfocr.py](https://github.com/LeoFCardoso/pdf2pdfocr) on your +document, which will then overwrite the file with an OCR'd version of +the file and exit. At which point, the consumption process will begin +with the newly modified file. + +The script's stdout and stderr will be logged line by line to the +webserver log, along with the exit code of the script. + +### Post-consumption script {#post_consume_script} + +Executed after the consumer has successfully processed a document and +has moved it into paperless. It receives the following environment +variables: + +- `DOCUMENT_ID` +- `DOCUMENT_FILE_NAME` +- `DOCUMENT_CREATED` +- `DOCUMENT_MODIFIED` +- `DOCUMENT_ADDED` +- `DOCUMENT_SOURCE_PATH` +- `DOCUMENT_ARCHIVE_PATH` +- `DOCUMENT_THUMBNAIL_PATH` +- `DOCUMENT_DOWNLOAD_URL` +- `DOCUMENT_THUMBNAIL_URL` +- `DOCUMENT_CORRESPONDENT` +- `DOCUMENT_TAGS` +- `DOCUMENT_ORIGINAL_FILENAME` + +The script can be in any language, but for a simple shell script +example, you can take a look at +[post-consumption-example.sh](https://github.com/paperless-ngx/paperless-ngx/blob/main/scripts/post-consumption-example.sh) +in this project. + +The post consumption script cannot cancel the consumption process. + +The script's stdout and stderr will be logged line by line to the +webserver log, along with the exit code of the script. + +#### Docker + +Assumed you have +`/home/foo/paperless-ngx/scripts/post-consumption-example.sh`. + +You can pass that script into the consumer container via a host mount in +your `docker-compose.yml`. + +```bash +... +consumer: + ... + volumes: + ... + - /home/paperless-ngx/scripts:/path/in/container/scripts/ +... +``` + +Example (docker-compose.yml): +`- /home/foo/paperless-ngx/scripts:/usr/src/paperless/scripts` + +which in turn requires the variable `PAPERLESS_POST_CONSUME_SCRIPT` in +`docker-compose.env` to point to +`/path/in/container/scripts/post-consumption-example.sh`. + +Example (docker-compose.env): +`PAPERLESS_POST_CONSUME_SCRIPT=/usr/src/paperless/scripts/post-consumption-example.sh` + +Troubleshooting: + +- Monitor the docker-compose log + `cd ~/paperless-ngx; docker-compose logs -f` +- Check your script's permission e.g. in case of permission error + `sudo chmod 755 post-consumption-example.sh` +- Pipe your scripts's output to a log file e.g. + `echo "${DOCUMENT_ID}" | tee --append /usr/src/paperless/scripts/post-consumption-example.log` + +## File name handling {#file_name_handling} + +By default, paperless stores your documents in the media directory and +renames them using the identifier which it has assigned to each +document. You will end up getting files like `0000123.pdf` in your media +directory. This isn't necessarily a bad thing, because you normally +don't have to access these files manually. However, if you wish to name +your files differently, you can do that by adjusting the +`PAPERLESS_FILENAME_FORMAT` configuration option. Paperless adds the +correct file extension e.g. `.pdf`, `.jpg` automatically. + +This variable allows you to configure the filename (folders are allowed) +using placeholders. For example, configuring this to + +```bash +PAPERLESS_FILENAME_FORMAT={created_year}/{correspondent}/{title} +``` + +will create a directory structure as follows: + +``` +2019/ + My bank/ + Statement January.pdf + Statement February.pdf +2020/ + My bank/ + Statement January.pdf + Letter.pdf + Letter_01.pdf + Shoe store/ + My new shoes.pdf +``` + +!!! warning + + Do not manually move your files in the media folder. Paperless remembers + the last filename a document was stored as. If you do rename a file, + paperless will report your files as missing and won't be able to find + them. + +Paperless provides the following placeholders within filenames: + +- `{asn}`: The archive serial number of the document, or "none". +- `{correspondent}`: The name of the correspondent, or "none". +- `{document_type}`: The name of the document type, or "none". +- `{tag_list}`: A comma separated list of all tags assigned to the + document. +- `{title}`: The title of the document. +- `{created}`: The full date (ISO format) the document was created. +- `{created_year}`: Year created only, formatted as the year with + century. +- `{created_year_short}`: Year created only, formatted as the year + without century, zero padded. +- `{created_month}`: Month created only (number 01-12). +- `{created_month_name}`: Month created name, as per locale +- `{created_month_name_short}`: Month created abbreviated name, as per + locale +- `{created_day}`: Day created only (number 01-31). +- `{added}`: The full date (ISO format) the document was added to + paperless. +- `{added_year}`: Year added only. +- `{added_year_short}`: Year added only, formatted as the year without + century, zero padded. +- `{added_month}`: Month added only (number 01-12). +- `{added_month_name}`: Month added name, as per locale +- `{added_month_name_short}`: Month added abbreviated name, as per + locale +- `{added_day}`: Day added only (number 01-31). + +Paperless will try to conserve the information from your database as +much as possible. However, some characters that you can use in document +titles and correspondent names (such as `: \ /` and a couple more) are +not allowed in filenames and will be replaced with dashes. + +If paperless detects that two documents share the same filename, +paperless will automatically append `_01`, `_02`, etc to the filename. +This happens if all the placeholders in a filename evaluate to the same +value. + +!!! tip + + You can affect how empty placeholders are treated by changing the + following setting to [true]{.title-ref}. + + ``` + PAPERLESS_FILENAME_FORMAT_REMOVE_NONE=True + ``` + + Doing this results in all empty placeholders resolving to "" instead + of "none" as stated above. Spaces before empty placeholders are + removed as well, empty directories are omitted. + +!!! tip + + Paperless checks the filename of a document whenever it is saved. + Therefore, you need to update the filenames of your documents and move + them after altering this setting by invoking the + [`document renamer `](). + +!!! warning + + Make absolutely sure you get the spelling of the placeholders right, or + else paperless will use the default naming scheme instead. + +!!! caution + + As of now, you could totally tell paperless to store your files anywhere + outside the media directory by setting + + ``` + PAPERLESS_FILENAME_FORMAT=../../my/custom/location/{title} + ``` + + However, keep in mind that inside docker, if files get stored outside of + the predefined volumes, they will be lost after a restart of paperless. + +## Storage paths + +One of the best things in Paperless is that you can not only access the +documents via the web interface, but also via the file system. + +When as single storage layout is not sufficient for your use case, +storage paths come to the rescue. Storage paths allow you to configure +more precisely where each document is stored in the file system. + +- Each storage path is a [PAPERLESS_FILENAME_FORMAT]{.title-ref} and + follows the rules described above +- Each document is assigned a storage path using the matching + algorithms described above, but can be overwritten at any time + +For example, you could define the following two storage paths: + +1. Normal communications are put into a folder structure sorted by + [year/correspondent]{.title-ref} +2. Communications with insurance companies are stored in a flat + structure with longer file names, but containing the full date of + the correspondence. + +``` +By Year = {created_year}/{correspondent}/{title} +Insurances = Insurances/{correspondent}/{created_year}-{created_month}-{created_day} {title} +``` + +If you then map these storage paths to the documents, you might get the +following result. For simplicity, [By Year]{.title-ref} defines the same +structure as in the previous example above. + +```text +2019/ # By Year + My bank/ + Statement January.pdf + Statement February.pdf + + Insurances/ # Insurances + Healthcare 123/ + 2022-01-01 Statement January.pdf + 2022-02-02 Letter.pdf + 2022-02-03 Letter.pdf + Dental 456/ + 2021-12-01 New Conditions.pdf +``` + +!!! tip + + Defining a storage path is optional. If no storage path is defined for a + document, the global [PAPERLESS_FILENAME_FORMAT]{.title-ref} is applied. + +!!! warning + + If you adjust the format of an existing storage path, old documents + don't get relocated automatically. You need to run the + [document renamer](/administration#renamer) to + adjust their pathes. + +## Celery Monitoring {#celery-monitoring} + +The monitoring tool +[Flower](https://flower.readthedocs.io/en/latest/index.html) can be used +to view more detailed information about the health of the celery workers +used for asynchronous tasks. This includes details on currently running, +queued and completed tasks, timing and more. Flower can also be used +with Prometheus, as it exports metrics. For details on its capabilities, +refer to the Flower documentation. + +To configure Flower further, create a [flowerconfig.py]{.title-ref} and +place it into the [src/paperless]{.title-ref} directory. For a Docker +installation, you can use volumes to accomplish this: + +```yaml +services: + # ... + webserver: + # ... + volumes: + - /path/to/my/flowerconfig.py:/usr/src/paperless/src/paperless/flowerconfig.py:ro +``` + +## Custom Container Initialization + +The Docker image includes the ability to run custom user scripts during +startup. This could be utilized for installing additional tools or +Python packages, for example. + +To utilize this, mount a folder containing your scripts to the custom +initialization directory, [/custom-cont-init.d]{.title-ref} and place +scripts you wish to run inside. For security, the folder must be owned +by `root` and should have permissions of `a=rx`. Additionally, scripts +must only be writable by `root`. + +Your scripts will be run directly before the webserver completes +startup. Scripts will be run by the [root]{.title-ref} user. +If you would like to switch users, the utility `gosu` is available and +preferred over `sudo`. + +This is an advanced functionality with which you could break functionality +or lose data. If you experience issues, please disable any custom scripts +and try again before reporting an issue. + +For example, using Docker Compose: + +```yaml +services: + # ... + webserver: + # ... + volumes: + - /path/to/my/scripts:/custom-cont-init.d:ro +``` + +## MySQL Caveats {#mysql-caveats} + +### Case Sensitivity + +The database interface does not provide a method to configure a MySQL +database to be case sensitive. This would prevent a user from creating a +tag `Name` and `NAME` as they are considered the same. + +Per Django documentation, to enable this requires manual intervention. +To enable case sensetive tables, you can execute the following command +against each table: + +`ALTER TABLE CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;` + +You can also set the default for new tables (this does NOT affect +existing tables) with: + +`ALTER DATABASE CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;` diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst deleted file mode 100644 index eda2ca259..000000000 --- a/docs/advanced_usage.rst +++ /dev/null @@ -1,419 +0,0 @@ -*************** -Advanced topics -*************** - -Paperless offers a couple features that automate certain tasks and make your life -easier. - -.. _advanced-matching: - -Matching tags, correspondents, document types, and storage paths -################################################################ - -Paperless will compare the matching algorithms defined by every tag, correspondent, -document type, and storage path in your database to see if they apply to the text -in a document. In other words, if you define a tag called ``Home Utility`` -that had a ``match`` property of ``bc hydro`` and a ``matching_algorithm`` of -``literal``, Paperless will automatically tag your newly-consumed document with -your ``Home Utility`` tag so long as the text ``bc hydro`` appears in the body -of the document somewhere. - -The matching logic is quite powerful. It supports searching the text of your -document with different algorithms, and as such, some experimentation may be -necessary to get things right. - -In order to have a tag, correspondent, document type, or storage path assigned -automatically to newly consumed documents, assign a match and matching algorithm -using the web interface. These settings define when to assign tags, correspondents, -document types, and storage paths to documents. - -The following algorithms are available: - -* **Any:** Looks for any occurrence of any word provided in match in the PDF. - If you define the match as ``Bank1 Bank2``, it will match documents containing - either of these terms. -* **All:** Requires that every word provided appears in the PDF, albeit not in the - order provided. -* **Literal:** Matches only if the match appears exactly as provided (i.e. preserve ordering) in the PDF. -* **Regular expression:** Parses the match as a regular expression and tries to - find a match within the document. -* **Fuzzy match:** I don't know. Look at the source. -* **Auto:** Tries to automatically match new documents. This does not require you - to set a match. See the notes below. - -When using the *any* or *all* matching algorithms, you can search for terms -that consist of multiple words by enclosing them in double quotes. For example, -defining a match text of ``"Bank of America" BofA`` using the *any* algorithm, -will match documents that contain either "Bank of America" or "BofA", but will -not match documents containing "Bank of South America". - -Then just save your tag, correspondent, document type, or storage path and run -another document through the consumer. Once complete, you should see the -newly-created document, automatically tagged with the appropriate data. - - -.. _advanced-automatic_matching: - -Automatic matching -================== - -Paperless-ngx comes with a new matching algorithm called *Auto*. This matching -algorithm tries to assign tags, correspondents, document types, and storage paths -to your documents based on how you have already assigned these on existing documents. -It uses a neural network under the hood. - -If, for example, all your bank statements of your account 123 at the Bank of -America are tagged with the tag "bofa_123" and the matching algorithm of this -tag is set to *Auto*, this neural network will examine your documents and -automatically learn when to assign this tag. - -Paperless tries to hide much of the involved complexity with this approach. -However, there are a couple caveats you need to keep in mind when using this -feature: - -* Changes to your documents are not immediately reflected by the matching - algorithm. The neural network needs to be *trained* on your documents after - changes. Paperless periodically (default: once each hour) checks for changes - and does this automatically for you. -* The Auto matching algorithm only takes documents into account which are NOT - placed in your inbox (i.e. have any inbox tags assigned to them). This ensures - that the neural network only learns from documents which you have correctly - tagged before. -* The matching algorithm can only work if there is a correlation between the - tag, correspondent, document type, or storage path and the document itself. - Your bank statements usually contain your bank account number and the name - of the bank, so this works reasonably well, However, tags such as "TODO" - cannot be automatically assigned. -* The matching algorithm needs a reasonable number of documents to identify when - to assign tags, correspondents, storage paths, and types. If one out of a - thousand documents has the correspondent "Very obscure web shop I bought - something five years ago", it will probably not assign this correspondent - automatically if you buy something from them again. The more documents, the better. -* Paperless also needs a reasonable amount of negative examples to decide when - not to assign a certain tag, correspondent, document type, or storage path. This will - usually be the case as you start filling up paperless with documents. - Example: If all your documents are either from "Webshop" and "Bank", paperless - will assign one of these correspondents to ANY new document, if both are set - to automatic matching. - -Hooking into the consumption process -#################################### - -Sometimes you may want to do something arbitrary whenever a document is -consumed. Rather than try to predict what you may want to do, Paperless lets -you execute scripts of your own choosing just before or after a document is -consumed using a couple simple hooks. - -Just write a script, put it somewhere that Paperless can read & execute, and -then put the path to that script in ``paperless.conf`` or ``docker-compose.env`` with the variable name -of either ``PAPERLESS_PRE_CONSUME_SCRIPT`` or -``PAPERLESS_POST_CONSUME_SCRIPT``. - -.. important:: - - These scripts are executed in a **blocking** process, which means that if - a script takes a long time to run, it can significantly slow down your - document consumption flow. If you want things to run asynchronously, - you'll have to fork the process in your script and exit. - - -Pre-consumption script -====================== - -Executed after the consumer sees a new document in the consumption folder, but -before any processing of the document is performed. This script can access the -following relevant environment variables set: - -* ``DOCUMENT_SOURCE_PATH`` - -A simple but common example for this would be creating a simple script like -this: - -``/usr/local/bin/ocr-pdf`` - -.. code:: bash - - #!/usr/bin/env bash - pdf2pdfocr.py -i ${DOCUMENT_SOURCE_PATH} - -``/etc/paperless.conf`` - -.. code:: bash - - ... - PAPERLESS_PRE_CONSUME_SCRIPT="/usr/local/bin/ocr-pdf" - ... - -This will pass the path to the document about to be consumed to ``/usr/local/bin/ocr-pdf``, -which will in turn call `pdf2pdfocr.py`_ on your document, which will then -overwrite the file with an OCR'd version of the file and exit. At which point, -the consumption process will begin with the newly modified file. - -.. _pdf2pdfocr.py: https://github.com/LeoFCardoso/pdf2pdfocr - -.. _advanced-post_consume_script: - -Post-consumption script -======================= - -Executed after the consumer has successfully processed a document and has moved it -into paperless. It receives the following environment variables: - -* ``DOCUMENT_ID`` -* ``DOCUMENT_FILE_NAME`` -* ``DOCUMENT_CREATED`` -* ``DOCUMENT_MODIFIED`` -* ``DOCUMENT_ADDED`` -* ``DOCUMENT_SOURCE_PATH`` -* ``DOCUMENT_ARCHIVE_PATH`` -* ``DOCUMENT_THUMBNAIL_PATH`` -* ``DOCUMENT_DOWNLOAD_URL`` -* ``DOCUMENT_THUMBNAIL_URL`` -* ``DOCUMENT_CORRESPONDENT`` -* ``DOCUMENT_TAGS`` -* ``DOCUMENT_ORIGINAL_FILENAME`` - -The script can be in any language, but for a simple shell script -example, you can take a look at `post-consumption-example.sh`_ in this project. - -The post consumption script cannot cancel the consumption process. - -Docker ------- -Assumed you have ``/home/foo/paperless-ngx/scripts/post-consumption-example.sh``. - -You can pass that script into the consumer container via a host mount in your ``docker-compose.yml``. - -.. code:: bash - - ... - consumer: - ... - volumes: - ... - - /home/paperless-ngx/scripts:/path/in/container/scripts/ - ... - -Example (docker-compose.yml): ``- /home/foo/paperless-ngx/scripts:/usr/src/paperless/scripts`` - -which in turn requires the variable ``PAPERLESS_POST_CONSUME_SCRIPT`` in ``docker-compose.env`` to point to ``/path/in/container/scripts/post-consumption-example.sh``. - -Example (docker-compose.env): ``PAPERLESS_POST_CONSUME_SCRIPT=/usr/src/paperless/scripts/post-consumption-example.sh`` - -Troubleshooting: - -- Monitor the docker-compose log ``cd ~/paperless-ngx; docker-compose logs -f`` -- Check your script's permission e.g. in case of permission error ``sudo chmod 755 post-consumption-example.sh`` -- Pipe your scripts's output to a log file e.g. ``echo "${DOCUMENT_ID}" | tee --append /usr/src/paperless/scripts/post-consumption-example.log`` - -.. _post-consumption-example.sh: https://github.com/paperless-ngx/paperless-ngx/blob/main/scripts/post-consumption-example.sh - -.. _advanced-file_name_handling: - -File name handling -################## - -By default, paperless stores your documents in the media directory and renames them -using the identifier which it has assigned to each document. You will end up getting -files like ``0000123.pdf`` in your media directory. This isn't necessarily a bad -thing, because you normally don't have to access these files manually. However, if -you wish to name your files differently, you can do that by adjusting the -``PAPERLESS_FILENAME_FORMAT`` configuration option. Paperless adds the correct -file extension e.g. ``.pdf``, ``.jpg`` automatically. - -This variable allows you to configure the filename (folders are allowed) using -placeholders. For example, configuring this to - -.. code:: bash - - PAPERLESS_FILENAME_FORMAT={created_year}/{correspondent}/{title} - -will create a directory structure as follows: - -.. code:: - - 2019/ - My bank/ - Statement January.pdf - Statement February.pdf - 2020/ - My bank/ - Statement January.pdf - Letter.pdf - Letter_01.pdf - Shoe store/ - My new shoes.pdf - -.. danger:: - - Do not manually move your files in the media folder. Paperless remembers the - last filename a document was stored as. If you do rename a file, paperless will - report your files as missing and won't be able to find them. - -Paperless provides the following placeholders within filenames: - -* ``{asn}``: The archive serial number of the document, or "none". -* ``{correspondent}``: The name of the correspondent, or "none". -* ``{document_type}``: The name of the document type, or "none". -* ``{tag_list}``: A comma separated list of all tags assigned to the document. -* ``{title}``: The title of the document. -* ``{created}``: The full date (ISO format) the document was created. -* ``{created_year}``: Year created only, formatted as the year with century. -* ``{created_year_short}``: Year created only, formatted as the year without century, zero padded. -* ``{created_month}``: Month created only (number 01-12). -* ``{created_month_name}``: Month created name, as per locale -* ``{created_month_name_short}``: Month created abbreviated name, as per locale -* ``{created_day}``: Day created only (number 01-31). -* ``{added}``: The full date (ISO format) the document was added to paperless. -* ``{added_year}``: Year added only. -* ``{added_year_short}``: Year added only, formatted as the year without century, zero padded. -* ``{added_month}``: Month added only (number 01-12). -* ``{added_month_name}``: Month added name, as per locale -* ``{added_month_name_short}``: Month added abbreviated name, as per locale -* ``{added_day}``: Day added only (number 01-31). - - -Paperless will try to conserve the information from your database as much as possible. -However, some characters that you can use in document titles and correspondent names (such -as ``: \ /`` and a couple more) are not allowed in filenames and will be replaced with dashes. - -If paperless detects that two documents share the same filename, paperless will automatically -append ``_01``, ``_02``, etc to the filename. This happens if all the placeholders in a filename -evaluate to the same value. - -.. hint:: - You can affect how empty placeholders are treated by changing the following setting to - `true`. - - .. code:: - - PAPERLESS_FILENAME_FORMAT_REMOVE_NONE=True - - Doing this results in all empty placeholders resolving to "" instead of "none" as stated above. - Spaces before empty placeholders are removed as well, empty directories are omitted. - -.. hint:: - - Paperless checks the filename of a document whenever it is saved. Therefore, - you need to update the filenames of your documents and move them after altering - this setting by invoking the :ref:`document renamer `. - -.. warning:: - - Make absolutely sure you get the spelling of the placeholders right, or else - paperless will use the default naming scheme instead. - -.. caution:: - - As of now, you could totally tell paperless to store your files anywhere outside - the media directory by setting - - .. code:: - - PAPERLESS_FILENAME_FORMAT=../../my/custom/location/{title} - - However, keep in mind that inside docker, if files get stored outside of the - predefined volumes, they will be lost after a restart of paperless. - - -Storage paths -############# - -One of the best things in Paperless is that you can not only access the documents via the -web interface, but also via the file system. - -When as single storage layout is not sufficient for your use case, storage paths come to -the rescue. Storage paths allow you to configure more precisely where each document is stored -in the file system. - -- Each storage path is a `PAPERLESS_FILENAME_FORMAT` and follows the rules described above -- Each document is assigned a storage path using the matching algorithms described above, but - can be overwritten at any time - -For example, you could define the following two storage paths: - -1. Normal communications are put into a folder structure sorted by `year/correspondent` -2. Communications with insurance companies are stored in a flat structure with longer file names, - but containing the full date of the correspondence. - -.. code:: - - By Year = {created_year}/{correspondent}/{title} - Insurances = Insurances/{correspondent}/{created_year}-{created_month}-{created_day} {title} - - -If you then map these storage paths to the documents, you might get the following result. -For simplicity, `By Year` defines the same structure as in the previous example above. - -.. code:: text - - 2019/ # By Year - My bank/ - Statement January.pdf - Statement February.pdf - - Insurances/ # Insurances - Healthcare 123/ - 2022-01-01 Statement January.pdf - 2022-02-02 Letter.pdf - 2022-02-03 Letter.pdf - Dental 456/ - 2021-12-01 New Conditions.pdf - - -.. hint:: - - Defining a storage path is optional. If no storage path is defined for a document, the global - `PAPERLESS_FILENAME_FORMAT` is applied. - -.. caution:: - - If you adjust the format of an existing storage path, old documents don't get relocated automatically. - You need to run the :ref:`document renamer ` to adjust their pathes. - -.. _advanced-celery-monitoring: - -Celery Monitoring -################# - -The monitoring tool `Flower `_ can be used to view more -detailed information about the health of the celery workers used for asynchronous tasks. This includes details -on currently running, queued and completed tasks, timing and more. Flower can also be used with Prometheus, as it -exports metrics. For details on its capabilities, refer to the Flower documentation. - -To configure Flower further, create a `flowerconfig.py` and place it into the `src/paperless` directory. For -a Docker installation, you can use volumes to accomplish this: - -.. code:: yaml - - services: - # ... - webserver: - # ... - volumes: - - /path/to/my/flowerconfig.py:/usr/src/paperless/src/paperless/flowerconfig.py:ro - -Custom Container Initialization -############################### - -The Docker image includes the ability to run custom user scripts during startup. This could be -utilized for installing additional tools or Python packages, for example. - -To utilize this, mount a folder containing your scripts to the custom initialization directory, `/custom-cont-init.d` -and place scripts you wish to run inside. For security, the folder and its contents must be owned by `root`. -Additionally, scripts must only be writable by `root`. - -Your scripts will be run directly before the webserver completes startup. Scripts will be run by the `root` user. -This is an advanced functionality with which you could break functionality or lose data. - -For example, using Docker Compose: - - -.. code:: yaml - - services: - # ... - webserver: - # ... - volumes: - - /path/to/my/scripts:/custom-cont-init.d:ro diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 000000000..b6e3325a5 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,318 @@ +# The REST API + +Paperless makes use of the [Django REST +Framework](http://django-rest-framework.org/) standard API interface. It +provides a browsable API for most of its endpoints, which you can +inspect at `http://:/api/`. This also documents +most of the available filters and ordering fields. + +The API provides 5 main endpoints: + +- `/api/documents/`: Full CRUD support, except POSTing new documents. + See below. +- `/api/correspondents/`: Full CRUD support. +- `/api/document_types/`: Full CRUD support. +- `/api/logs/`: Read-Only. +- `/api/tags/`: Full CRUD support. +- `/api/mail_accounts/`: Full CRUD support. +- `/api/mail_rules/`: Full CRUD support. + +All of these endpoints except for the logging endpoint allow you to +fetch, edit and delete individual objects by appending their primary key +to the path, for example `/api/documents/454/`. + +The objects served by the document endpoint contain the following +fields: + +- `id`: ID of the document. Read-only. +- `title`: Title of the document. +- `content`: Plain text content of the document. +- `tags`: List of IDs of tags assigned to this document, or empty + list. +- `document_type`: Document type of this document, or null. +- `correspondent`: Correspondent of this document or null. +- `created`: The date time at which this document was created. +- `created_date`: The date (YYYY-MM-DD) at which this document was + created. Optional. If also passed with created, this is ignored. +- `modified`: The date at which this document was last edited in + paperless. Read-only. +- `added`: The date at which this document was added to paperless. + Read-only. +- `archive_serial_number`: The identifier of this document in a + physical document archive. +- `original_file_name`: Verbose filename of the original document. + Read-only. +- `archived_file_name`: Verbose filename of the archived document. + Read-only. Null if no archived document is available. + +## Downloading documents + +In addition to that, the document endpoint offers these additional +actions on individual documents: + +- `/api/documents//download/`: Download the document. +- `/api/documents//preview/`: Display the document inline, without + downloading it. +- `/api/documents//thumb/`: Download the PNG thumbnail of a + document. + +Paperless generates archived PDF/A documents from consumed files and +stores both the original files as well as the archived files. By +default, the endpoints for previews and downloads serve the archived +file, if it is available. Otherwise, the original file is served. Some +document cannot be archived. + +The endpoints correctly serve the response header fields +`Content-Disposition` and `Content-Type` to indicate the filename for +download and the type of content of the document. + +In order to download or preview the original document when an archived +document is available, supply the query parameter `original=true`. + +!!! tip + + Paperless used to provide these functionality at `/fetch//preview`, + `/fetch//thumb` and `/fetch//doc`. Redirects to the new URLs are + in place. However, if you use these old URLs to access documents, you + should update your app or script to use the new URLs. + +## Getting document metadata + +The api also has an endpoint to retrieve read-only metadata about +specific documents. this information is not served along with the +document objects, since it requires reading files and would therefore +slow down document lists considerably. + +Access the metadata of a document with an ID `id` at +`/api/documents//metadata/`. + +The endpoint reports the following data: + +- `original_checksum`: MD5 checksum of the original document. +- `original_size`: Size of the original document, in bytes. +- `original_mime_type`: Mime type of the original document. +- `media_filename`: Current filename of the document, under which it + is stored inside the media directory. +- `has_archive_version`: True, if this document is archived, false + otherwise. +- `original_metadata`: A list of metadata associated with the original + document. See below. +- `archive_checksum`: MD5 checksum of the archived document, or null. +- `archive_size`: Size of the archived document in bytes, or null. +- `archive_metadata`: Metadata associated with the archived document, + or null. See below. + +File metadata is reported as a list of objects in the following form: + +```json +[ + { + "namespace": "http://ns.adobe.com/pdf/1.3/", + "prefix": "pdf", + "key": "Producer", + "value": "SparklePDF, Fancy edition" + } +] +``` + +`namespace` and `prefix` can be null. The actual metadata reported +depends on the file type and the metadata available in that specific +document. Paperless only reports PDF metadata at this point. + +## Authorization + +The REST api provides three different forms of authentication. + +1. Basic authentication + + Authorize by providing a HTTP header in the form + + ``` + Authorization: Basic + ``` + + where `credentials` is a base64-encoded string of + `:` + +2. Session authentication + + When you're logged into paperless in your browser, you're + automatically logged into the API as well and don't need to provide + any authorization headers. + +3. Token authentication + + Paperless also offers an endpoint to acquire authentication tokens. + + POST a username and password as a form or json string to + `/api/token/` and paperless will respond with a token, if the login + data is correct. This token can be used to authenticate other + requests with the following HTTP header: + + ``` + Authorization: Token + ``` + + Tokens can be managed and revoked in the paperless admin. + +## Searching for documents + +Full text searching is available on the `/api/documents/` endpoint. Two +specific query parameters cause the API to return full text search +results: + +- `/api/documents/?query=your%20search%20query`: Search for a document + using a full text query. For details on the syntax, see [Basic Usage - Searching](usage#basic-usage_searching). +- `/api/documents/?more_like=1234`: Search for documents similar to + the document with id 1234. + +Pagination works exactly the same as it does for normal requests on this +endpoint. + +Certain limitations apply to full text queries: + +- Results are always sorted by search score. The results matching the + query best will show up first. +- Only a small subset of filtering parameters are supported. + +Furthermore, each returned document has an additional `__search_hit__` +attribute with various information about the search results: + +``` +{ + "count": 31, + "next": "http://localhost:8000/api/documents/?page=2&query=test", + "previous": null, + "results": [ + + ... + + { + "id": 123, + "title": "title", + "content": "content", + + ... + + "__search_hit__": { + "score": 0.343, + "highlights": "text Test text", + "rank": 23 + } + }, + + ... + + ] +} +``` + +- `score` is an indication how well this document matches the query + relative to the other search results. +- `highlights` is an excerpt from the document content and highlights + the search terms with `` tags as shown above. +- `rank` is the index of the search results. The first result will + have rank 0. + +### `/api/search/autocomplete/` + +Get auto completions for a partial search term. + +Query parameters: + +- `term`: The incomplete term. +- `limit`: Amount of results. Defaults to 10. + +Results returned by the endpoint are ordered by importance of the term +in the document index. The first result is the term that has the highest +Tf/Idf score in the index. + +```json +["term1", "term3", "term6", "term4"] +``` + +## POSTing documents {#file-uploads} + +The API provides a special endpoint for file uploads: + +`/api/documents/post_document/` + +POST a multipart form to this endpoint, where the form field `document` +contains the document that you want to upload to paperless. The filename +is sanitized and then used to store the document in a temporary +directory, and the consumer will be instructed to consume the document +from there. + +The endpoint supports the following optional form fields: + +- `title`: Specify a title that the consumer should use for the + document. +- `created`: Specify a DateTime where the document was created (e.g. + "2016-04-19" or "2016-04-19 06:15:00+02:00"). +- `correspondent`: Specify the ID of a correspondent that the consumer + should use for the document. +- `document_type`: Similar to correspondent. +- `tags`: Similar to correspondent. Specify this multiple times to + have multiple tags added to the document. + +The endpoint will immediately return "OK" if the document consumption +process was started successfully. No additional status information about +the consumption process itself is available, since that happens in a +different process. + +## API Versioning + +The REST API is versioned since Paperless-ngx 1.3.0. + +- Versioning ensures that changes to the API don't break older + clients. +- Clients specify the specific version of the API they wish to use + with every request and Paperless will handle the request using the + specified API version. +- Even if the underlying data model changes, older API versions will + always serve compatible data. +- If no version is specified, Paperless will serve version 1 to ensure + compatibility with older clients that do not request a specific API + version. + +API versions are specified by submitting an additional HTTP `Accept` +header with every request: + +``` +Accept: application/json; version=6 +``` + +If an invalid version is specified, Paperless 1.3.0 will respond with +"406 Not Acceptable" and an error message in the body. Earlier +versions of Paperless will serve API version 1 regardless of whether a +version is specified via the `Accept` header. + +If a client wishes to verify whether it is compatible with any given +server, the following procedure should be performed: + +1. Perform an _authenticated_ request against any API endpoint. If the + server is on version 1.3.0 or newer, the server will add two custom + headers to the response: + + ``` + X-Api-Version: 2 + X-Version: 1.3.0 + ``` + +2. Determine whether the client is compatible with this server based on + the presence/absence of these headers and their values if present. + +### API Changelog + +#### Version 1 + +Initial API version. + +#### Version 2 + +- Added field `Tag.color`. This read/write string field contains a hex + color such as `#a6cee3`. +- Added read-only field `Tag.text_color`. This field contains the text + color to use for a specific tag, which is either black or white + depending on the brightness of `Tag.color`. +- Removed field `Tag.colour`. diff --git a/docs/api.rst b/docs/api.rst deleted file mode 100644 index 1e70b19fa..000000000 --- a/docs/api.rst +++ /dev/null @@ -1,303 +0,0 @@ - -************ -The REST API -************ - - -Paperless makes use of the `Django REST Framework`_ standard API interface. -It provides a browsable API for most of its endpoints, which you can inspect -at ``http://:/api/``. This also documents most of the -available filters and ordering fields. - -.. _Django REST Framework: http://django-rest-framework.org/ - -The API provides 5 main endpoints: - -* ``/api/documents/``: Full CRUD support, except POSTing new documents. See below. -* ``/api/correspondents/``: Full CRUD support. -* ``/api/document_types/``: Full CRUD support. -* ``/api/logs/``: Read-Only. -* ``/api/tags/``: Full CRUD support. - -All of these endpoints except for the logging endpoint -allow you to fetch, edit and delete individual objects -by appending their primary key to the path, for example ``/api/documents/454/``. - -The objects served by the document endpoint contain the following fields: - -* ``id``: ID of the document. Read-only. -* ``title``: Title of the document. -* ``content``: Plain text content of the document. -* ``tags``: List of IDs of tags assigned to this document, or empty list. -* ``document_type``: Document type of this document, or null. -* ``correspondent``: Correspondent of this document or null. -* ``created``: The date time at which this document was created. -* ``created_date``: The date (YYYY-MM-DD) at which this document was created. Optional. If also passed with created, this is ignored. -* ``modified``: The date at which this document was last edited in paperless. Read-only. -* ``added``: The date at which this document was added to paperless. Read-only. -* ``archive_serial_number``: The identifier of this document in a physical document archive. -* ``original_file_name``: Verbose filename of the original document. Read-only. -* ``archived_file_name``: Verbose filename of the archived document. Read-only. Null if no archived document is available. - - -Downloading documents -##################### - -In addition to that, the document endpoint offers these additional actions on -individual documents: - -* ``/api/documents//download/``: Download the document. -* ``/api/documents//preview/``: Display the document inline, - without downloading it. -* ``/api/documents//thumb/``: Download the PNG thumbnail of a document. - -Paperless generates archived PDF/A documents from consumed files and stores both -the original files as well as the archived files. By default, the endpoints -for previews and downloads serve the archived file, if it is available. -Otherwise, the original file is served. -Some document cannot be archived. - -The endpoints correctly serve the response header fields ``Content-Disposition`` -and ``Content-Type`` to indicate the filename for download and the type of content of -the document. - -In order to download or preview the original document when an archived document is available, -supply the query parameter ``original=true``. - -.. hint:: - - Paperless used to provide these functionality at ``/fetch//preview``, - ``/fetch//thumb`` and ``/fetch//doc``. Redirects to the new URLs - are in place. However, if you use these old URLs to access documents, you - should update your app or script to use the new URLs. - - -Getting document metadata -######################### - -The api also has an endpoint to retrieve read-only metadata about specific documents. this -information is not served along with the document objects, since it requires reading -files and would therefore slow down document lists considerably. - -Access the metadata of a document with an ID ``id`` at ``/api/documents//metadata/``. - -The endpoint reports the following data: - -* ``original_checksum``: MD5 checksum of the original document. -* ``original_size``: Size of the original document, in bytes. -* ``original_mime_type``: Mime type of the original document. -* ``media_filename``: Current filename of the document, under which it is stored inside the media directory. -* ``has_archive_version``: True, if this document is archived, false otherwise. -* ``original_metadata``: A list of metadata associated with the original document. See below. -* ``archive_checksum``: MD5 checksum of the archived document, or null. -* ``archive_size``: Size of the archived document in bytes, or null. -* ``archive_metadata``: Metadata associated with the archived document, or null. See below. - -File metadata is reported as a list of objects in the following form: - -.. code:: json - - [ - { - "namespace": "http://ns.adobe.com/pdf/1.3/", - "prefix": "pdf", - "key": "Producer", - "value": "SparklePDF, Fancy edition" - }, - ] - -``namespace`` and ``prefix`` can be null. The actual metadata reported depends on the file type and the metadata -available in that specific document. Paperless only reports PDF metadata at this point. - -Authorization -############# - -The REST api provides three different forms of authentication. - -1. Basic authentication - - Authorize by providing a HTTP header in the form - - .. code:: - - Authorization: Basic - - where ``credentials`` is a base64-encoded string of ``:`` - -2. Session authentication - - When you're logged into paperless in your browser, you're automatically - logged into the API as well and don't need to provide any authorization - headers. - -3. Token authentication - - Paperless also offers an endpoint to acquire authentication tokens. - - POST a username and password as a form or json string to ``/api/token/`` - and paperless will respond with a token, if the login data is correct. - This token can be used to authenticate other requests with the - following HTTP header: - - .. code:: - - Authorization: Token - - Tokens can be managed and revoked in the paperless admin. - -Searching for documents -####################### - -Full text searching is available on the ``/api/documents/`` endpoint. Two specific -query parameters cause the API to return full text search results: - -* ``/api/documents/?query=your%20search%20query``: Search for a document using a full text query. - For details on the syntax, see :ref:`basic-usage_searching`. - -* ``/api/documents/?more_like=1234``: Search for documents similar to the document with id 1234. - -Pagination works exactly the same as it does for normal requests on this endpoint. - -Certain limitations apply to full text queries: - -* Results are always sorted by search score. The results matching the query best will show up first. - -* Only a small subset of filtering parameters are supported. - -Furthermore, each returned document has an additional ``__search_hit__`` attribute with various information -about the search results: - -.. code:: - - { - "count": 31, - "next": "http://localhost:8000/api/documents/?page=2&query=test", - "previous": null, - "results": [ - - ... - - { - "id": 123, - "title": "title", - "content": "content", - - ... - - "__search_hit__": { - "score": 0.343, - "highlights": "text Test text", - "rank": 23 - } - }, - - ... - - ] - } - -* ``score`` is an indication how well this document matches the query relative to the other search results. -* ``highlights`` is an excerpt from the document content and highlights the search terms with ```` tags as shown above. -* ``rank`` is the index of the search results. The first result will have rank 0. - -``/api/search/autocomplete/`` -============================= - -Get auto completions for a partial search term. - -Query parameters: - -* ``term``: The incomplete term. -* ``limit``: Amount of results. Defaults to 10. - -Results returned by the endpoint are ordered by importance of the term in the -document index. The first result is the term that has the highest Tf/Idf score -in the index. - -.. code:: json - - [ - "term1", - "term3", - "term6", - "term4" - ] - - -.. _api-file_uploads: - -POSTing documents -################# - -The API provides a special endpoint for file uploads: - -``/api/documents/post_document/`` - -POST a multipart form to this endpoint, where the form field ``document`` contains -the document that you want to upload to paperless. The filename is sanitized and -then used to store the document in a temporary directory, and the consumer will -be instructed to consume the document from there. - -The endpoint supports the following optional form fields: - -* ``title``: Specify a title that the consumer should use for the document. -* ``created``: Specify a DateTime where the document was created (e.g. "2016-04-19" or "2016-04-19 06:15:00+02:00"). -* ``correspondent``: Specify the ID of a correspondent that the consumer should use for the document. -* ``document_type``: Similar to correspondent. -* ``tags``: Similar to correspondent. Specify this multiple times to have multiple tags added - to the document. - - -The endpoint will immediately return "OK" if the document consumption process -was started successfully. No additional status information about the consumption -process itself is available, since that happens in a different process. - - -.. _api-versioning: - -API Versioning -############## - -The REST API is versioned since Paperless-ngx 1.3.0. - -* Versioning ensures that changes to the API don't break older clients. -* Clients specify the specific version of the API they wish to use with every request and Paperless will handle the request using the specified API version. -* Even if the underlying data model changes, older API versions will always serve compatible data. -* If no version is specified, Paperless will serve version 1 to ensure compatibility with older clients that do not request a specific API version. - -API versions are specified by submitting an additional HTTP ``Accept`` header with every request: - -.. code:: - - Accept: application/json; version=6 - -If an invalid version is specified, Paperless 1.3.0 will respond with "406 Not Acceptable" and an error message in the body. -Earlier versions of Paperless will serve API version 1 regardless of whether a version is specified via the ``Accept`` header. - -If a client wishes to verify whether it is compatible with any given server, the following procedure should be performed: - -1. Perform an *authenticated* request against any API endpoint. If the server is on version 1.3.0 or newer, the server will - add two custom headers to the response: - - .. code:: - - X-Api-Version: 2 - X-Version: 1.3.0 - -2. Determine whether the client is compatible with this server based on the presence/absence of these headers and their values if present. - - -API Changelog -============= - -Version 1 ---------- - -Initial API version. - -Version 2 ---------- - -* Added field ``Tag.color``. This read/write string field contains a hex color such as ``#a6cee3``. -* Added read-only field ``Tag.text_color``. This field contains the text color to use for a specific tag, which is either black or white depending on the brightness of ``Tag.color``. -* Removed field ``Tag.colour``. diff --git a/docs/_static/.keep b/docs/assets/.keep similarity index 100% rename from docs/_static/.keep rename to docs/assets/.keep diff --git a/docs/assets/extra.css b/docs/assets/extra.css new file mode 100644 index 000000000..da572b75d --- /dev/null +++ b/docs/assets/extra.css @@ -0,0 +1,36 @@ +:root > * { + --md-primary-fg-color: #17541f; + --md-primary-fg-color--dark: #17541f; + --md-primary-fg-color--light: #17541f; + --md-accent-fg-color: #2b8a38; + --md-typeset-a-color: #21652a; +} + +[data-md-color-scheme="slate"] { + --md-hue: 222; +} + +@media (min-width: 400px) { + .grid-left { + width: 33%; + float: left; + } + .grid-right { + width: 62%; + margin-left: 4%; + float: left; + } +} + +.grid-left > p { + margin-bottom: 2rem; +} + + +.grid-right p { + margin: 0; +} + +.index-callout { + margin-right: .5rem; +} diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..10013865d592c990882889b722908a0eadcd7dbd GIT binary patch literal 768 zcmV+b1ONPqP)-uXRkj}d*{wyJ|E9L@8Kc15f|MDkwc1ORy#tFIT|)96TD~c=-YyyWu}Ij^xF`v6Vr`$5CQI)D%<&r)@`ZXp z(dtntJdnZaUxj)gORN{}fvmBP2y^#<2CJtEunm*%YOs2Y{m=U$zYqfQq=Q__6eSK; zxuj8S!U*}E=3B3g3!pkk*ML(4sY;9;p)8D%XT^V_0LCC8VtwBbd4dnwUWml6gIPp0 z+w=^PkHGqKSpiS@IuML|-(WU=mFh;Z@Wi3u33y?sF;%i!hnZ|UeO`2Yw6ewVmI+Lf zHgB4M^HI*hf|NA=H4Tvuf&5HmplP$bf|Zr$Eu9$Yp2&tEq9-6$SLm!vjFeNw0w>k; z0Qs@WnRvxc+gr>u9dtsQC(B_;An0>YH_E+uflSu4}$ zE0JdkfExv@;hDk}eoivdAtU)2{GKxTv^@}Tybxp^57FwQtnNz^FiH82M_E2ZGBUjl zxpzx6&npRlo9{UyXhNdim?QCVmXJ9|jngV8J)T8X7Ooz{BGPk4y&B^)nU{0f1}gRK=c#P4NV-$M2P y19bb)w+e=efOrZEbXC*51w + + + + + diff --git a/docs/assets/logo_full_black.svg b/docs/assets/logo_full_black.svg new file mode 100644 index 000000000..bf0d4a485 --- /dev/null +++ b/docs/assets/logo_full_black.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/assets/logo_full_white.svg b/docs/assets/logo_full_white.svg new file mode 100644 index 000000000..25451ee3b --- /dev/null +++ b/docs/assets/logo_full_white.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_static/recommended_workflow.png b/docs/assets/recommended_workflow.png similarity index 100% rename from docs/_static/recommended_workflow.png rename to docs/assets/recommended_workflow.png diff --git a/docs/_static/screenshots/bulk-edit.png b/docs/assets/screenshots/bulk-edit.png similarity index 100% rename from docs/_static/screenshots/bulk-edit.png rename to docs/assets/screenshots/bulk-edit.png diff --git a/docs/_static/screenshots/correspondents.png b/docs/assets/screenshots/correspondents.png similarity index 100% rename from docs/_static/screenshots/correspondents.png rename to docs/assets/screenshots/correspondents.png diff --git a/docs/_static/screenshots/dashboard.png b/docs/assets/screenshots/dashboard.png similarity index 100% rename from docs/_static/screenshots/dashboard.png rename to docs/assets/screenshots/dashboard.png diff --git a/docs/_static/screenshots/documents-filter.png b/docs/assets/screenshots/documents-filter.png similarity index 100% rename from docs/_static/screenshots/documents-filter.png rename to docs/assets/screenshots/documents-filter.png diff --git a/docs/_static/screenshots/documents-largecards.png b/docs/assets/screenshots/documents-largecards.png similarity index 100% rename from docs/_static/screenshots/documents-largecards.png rename to docs/assets/screenshots/documents-largecards.png diff --git a/docs/_static/screenshots/documents-smallcards-dark.png b/docs/assets/screenshots/documents-smallcards-dark.png similarity index 100% rename from docs/_static/screenshots/documents-smallcards-dark.png rename to docs/assets/screenshots/documents-smallcards-dark.png diff --git a/docs/_static/screenshots/documents-smallcards.png b/docs/assets/screenshots/documents-smallcards.png similarity index 100% rename from docs/_static/screenshots/documents-smallcards.png rename to docs/assets/screenshots/documents-smallcards.png diff --git a/docs/_static/screenshots/documents-table.png b/docs/assets/screenshots/documents-table.png similarity index 100% rename from docs/_static/screenshots/documents-table.png rename to docs/assets/screenshots/documents-table.png diff --git a/docs/_static/screenshots/documents-wchrome-dark.png b/docs/assets/screenshots/documents-wchrome-dark.png similarity index 100% rename from docs/_static/screenshots/documents-wchrome-dark.png rename to docs/assets/screenshots/documents-wchrome-dark.png diff --git a/docs/_static/screenshots/documents-wchrome.png b/docs/assets/screenshots/documents-wchrome.png similarity index 100% rename from docs/_static/screenshots/documents-wchrome.png rename to docs/assets/screenshots/documents-wchrome.png diff --git a/docs/_static/screenshots/editing.png b/docs/assets/screenshots/editing.png similarity index 100% rename from docs/_static/screenshots/editing.png rename to docs/assets/screenshots/editing.png diff --git a/docs/_static/screenshots/logs.png b/docs/assets/screenshots/logs.png similarity index 100% rename from docs/_static/screenshots/logs.png rename to docs/assets/screenshots/logs.png diff --git a/docs/assets/screenshots/mail-rules-edited.png b/docs/assets/screenshots/mail-rules-edited.png new file mode 100644 index 0000000000000000000000000000000000000000..42db1d673d34408f9c1d7f0dd57b423be43b3764 GIT binary patch literal 77537 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/_static/screenshots/mobile.png b/docs/assets/screenshots/mobile.png similarity index 100% rename from docs/_static/screenshots/mobile.png rename to docs/assets/screenshots/mobile.png diff --git a/docs/_static/screenshots/new-tag.png b/docs/assets/screenshots/new-tag.png similarity index 100% rename from docs/_static/screenshots/new-tag.png rename to docs/assets/screenshots/new-tag.png diff --git a/docs/_static/screenshots/search-preview.png b/docs/assets/screenshots/search-preview.png similarity index 100% rename from docs/_static/screenshots/search-preview.png rename to docs/assets/screenshots/search-preview.png diff --git a/docs/_static/screenshots/search-results.png b/docs/assets/screenshots/search-results.png similarity index 100% rename from docs/_static/screenshots/search-results.png rename to docs/assets/screenshots/search-results.png diff --git a/docs/changelog.md b/docs/changelog.md index 1caa00220..58591bd2d 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,7 +1,230 @@ # Changelog +## paperless-ngx 1.10.1 + +### Features + +- Feature: Allows documents in WebP format [@stumpylog](https://github.com/stumpylog) ([#1984](https://github.com/paperless-ngx/paperless-ngx/pull/1984)) + +### Bug Fixes + +- Fix: frontend tasks display in 1.10.0 [@shamoon](https://github.com/shamoon) ([#2073](https://github.com/paperless-ngx/paperless-ngx/pull/2073)) +- Bugfix: Custom startup commands weren't run as root [@stumpylog](https://github.com/stumpylog) ([#2069](https://github.com/paperless-ngx/paperless-ngx/pull/2069)) +- Bugfix: Add libatomic for armv7 compatibility [@stumpylog](https://github.com/stumpylog) ([#2066](https://github.com/paperless-ngx/paperless-ngx/pull/2066)) +- Bugfix: Don't silence an exception when trying to handle file naming [@stumpylog](https://github.com/stumpylog) ([#2062](https://github.com/paperless-ngx/paperless-ngx/pull/2062)) +- Bugfix: Some tesseract languages aren't detected as installed. [@stumpylog](https://github.com/stumpylog) ([#2057](https://github.com/paperless-ngx/paperless-ngx/pull/2057)) + +### Maintenance + +- Chore: Use a maintained upload-release-asset [@stumpylog](https://github.com/stumpylog) ([#2055](https://github.com/paperless-ngx/paperless-ngx/pull/2055)) + +### Dependencies + +
    + 5 changes + +- Bump tslib from 2.4.0 to 2.4.1 in /src-ui @dependabot ([#2076](https://github.com/paperless-ngx/paperless-ngx/pull/2076)) +- Bump @angular-builders/jest from 14.0.1 to 14.1.0 in /src-ui @dependabot ([#2079](https://github.com/paperless-ngx/paperless-ngx/pull/2079)) +- Bump jest-preset-angular from 12.2.2 to 12.2.3 in /src-ui @dependabot ([#2078](https://github.com/paperless-ngx/paperless-ngx/pull/2078)) +- Bump ngx-file-drop from 14.0.1 to 14.0.2 in /src-ui @dependabot ([#2080](https://github.com/paperless-ngx/paperless-ngx/pull/2080)) +- Bump @ngneat/dirty-check-forms from 3.0.2 to 3.0.3 in /src-ui @dependabot ([#2077](https://github.com/paperless-ngx/paperless-ngx/pull/2077)) +
    + +### All App Changes + +- Bump tslib from 2.4.0 to 2.4.1 in /src-ui @dependabot ([#2076](https://github.com/paperless-ngx/paperless-ngx/pull/2076)) +- Bump @angular-builders/jest from 14.0.1 to 14.1.0 in /src-ui @dependabot ([#2079](https://github.com/paperless-ngx/paperless-ngx/pull/2079)) +- Bump jest-preset-angular from 12.2.2 to 12.2.3 in /src-ui @dependabot ([#2078](https://github.com/paperless-ngx/paperless-ngx/pull/2078)) +- Bump ngx-file-drop from 14.0.1 to 14.0.2 in /src-ui @dependabot ([#2080](https://github.com/paperless-ngx/paperless-ngx/pull/2080)) +- Bump @ngneat/dirty-check-forms from 3.0.2 to 3.0.3 in /src-ui @dependabot ([#2077](https://github.com/paperless-ngx/paperless-ngx/pull/2077)) +- Fix: frontend tasks display in 1.10.0 [@shamoon](https://github.com/shamoon) ([#2073](https://github.com/paperless-ngx/paperless-ngx/pull/2073)) +- Bugfix: Don't silence an exception when trying to handle file naming [@stumpylog](https://github.com/stumpylog) ([#2062](https://github.com/paperless-ngx/paperless-ngx/pull/2062)) +- Bugfix: Some tesseract languages aren't detected as installed. [@stumpylog](https://github.com/stumpylog) ([#2057](https://github.com/paperless-ngx/paperless-ngx/pull/2057)) + +## paperless-ngx 1.10.0 + +### Features + +- Feature: Capture stdout \& stderr of the pre/post consume scripts [@stumpylog](https://github.com/stumpylog) ([#1967](https://github.com/paperless-ngx/paperless-ngx/pull/1967)) +- Feature: Allow running custom container initialization scripts [@stumpylog](https://github.com/stumpylog) ([#1838](https://github.com/paperless-ngx/paperless-ngx/pull/1838)) +- Feature: Add more file name formatting options [@stumpylog](https://github.com/stumpylog) ([#1906](https://github.com/paperless-ngx/paperless-ngx/pull/1906)) +- Feature: 1.9.2 UI tweaks [@shamoon](https://github.com/shamoon) ([#1886](https://github.com/paperless-ngx/paperless-ngx/pull/1886)) +- Feature: Optional celery monitoring with Flower [@stumpylog](https://github.com/stumpylog) ([#1810](https://github.com/paperless-ngx/paperless-ngx/pull/1810)) +- Feature: Save pending tasks for frontend [@stumpylog](https://github.com/stumpylog) ([#1816](https://github.com/paperless-ngx/paperless-ngx/pull/1816)) +- Feature: Improved processing for automatic matching [@stumpylog](https://github.com/stumpylog) ([#1609](https://github.com/paperless-ngx/paperless-ngx/pull/1609)) +- Feature: Transition to celery for background tasks [@stumpylog](https://github.com/stumpylog) ([#1648](https://github.com/paperless-ngx/paperless-ngx/pull/1648)) +- Feature: UI Welcome Tour [@shamoon](https://github.com/shamoon) ([#1644](https://github.com/paperless-ngx/paperless-ngx/pull/1644)) +- Feature: slim sidebar [@shamoon](https://github.com/shamoon) ([#1641](https://github.com/paperless-ngx/paperless-ngx/pull/1641)) +- change default matching algo to auto and move to constant [@NiFNi](https://github.com/NiFNi) ([#1754](https://github.com/paperless-ngx/paperless-ngx/pull/1754)) +- Feature: Enable end to end Tika testing in CI [@stumpylog](https://github.com/stumpylog) ([#1757](https://github.com/paperless-ngx/paperless-ngx/pull/1757)) +- Feature: frontend update checking settings [@shamoon](https://github.com/shamoon) ([#1692](https://github.com/paperless-ngx/paperless-ngx/pull/1692)) +- Feature: Upgrade to qpdf 11, pikepdf 6 \& ocrmypdf 14 [@stumpylog](https://github.com/stumpylog) ([#1642](https://github.com/paperless-ngx/paperless-ngx/pull/1642)) + +### Bug Fixes + +- Bugfix: Fix created_date being a string [@stumpylog](https://github.com/stumpylog) ([#2023](https://github.com/paperless-ngx/paperless-ngx/pull/2023)) +- Bugfix: Fixes an issue with mixed text and images when redoing OCR [@stumpylog](https://github.com/stumpylog) ([#2017](https://github.com/paperless-ngx/paperless-ngx/pull/2017)) +- Bugfix: Always re-try barcodes with pdf2image [@stumpylog](https://github.com/stumpylog) ([#1953](https://github.com/paperless-ngx/paperless-ngx/pull/1953)) +- Fix: using `CONSUMER_SUBDIRS_AS_TAGS` causes failure with Celery in `dev` [@shamoon](https://github.com/shamoon) ([#1942](https://github.com/paperless-ngx/paperless-ngx/pull/1942)) +- Fix mail consumption broken in `dev` after move to celery [@shamoon](https://github.com/shamoon) ([#1934](https://github.com/paperless-ngx/paperless-ngx/pull/1934)) +- Bugfix: Prevent file handling from running with stale data [@stumpylog](https://github.com/stumpylog) ([#1905](https://github.com/paperless-ngx/paperless-ngx/pull/1905)) +- Chore: Reduce nuisance CI test failures [@stumpylog](https://github.com/stumpylog) ([#1922](https://github.com/paperless-ngx/paperless-ngx/pull/1922)) +- Bugfix: Unintentional deletion of feature tagged Docker images [@stumpylog](https://github.com/stumpylog) ([#1896](https://github.com/paperless-ngx/paperless-ngx/pull/1896)) +- Fix: independent control of saved views [@shamoon](https://github.com/shamoon) ([#1868](https://github.com/paperless-ngx/paperless-ngx/pull/1868)) +- Fix: frontend relative date searches [@shamoon](https://github.com/shamoon) ([#1865](https://github.com/paperless-ngx/paperless-ngx/pull/1865)) +- Chore: Fixes pipenv issues [@stumpylog](https://github.com/stumpylog) ([#1873](https://github.com/paperless-ngx/paperless-ngx/pull/1873)) +- Bugfix: Handle password protected PDFs during barcode detection [@stumpylog](https://github.com/stumpylog) ([#1858](https://github.com/paperless-ngx/paperless-ngx/pull/1858)) +- Fix: Allows configuring barcodes with pdf2image instead of pikepdf [@stumpylog](https://github.com/stumpylog) ([#1857](https://github.com/paperless-ngx/paperless-ngx/pull/1857)) +- Bugfix: Reverts the change around skip_noarchive [@stumpylog](https://github.com/stumpylog) ([#1829](https://github.com/paperless-ngx/paperless-ngx/pull/1829)) +- Fix: missing loadViewConfig breaks loading saved view [@shamoon](https://github.com/shamoon) ([#1792](https://github.com/paperless-ngx/paperless-ngx/pull/1792)) +- Bugfix: Fallback to pdf2image if pikepdf fails [@stumpylog](https://github.com/stumpylog) ([#1745](https://github.com/paperless-ngx/paperless-ngx/pull/1745)) +- Fix: creating new storage path on document edit fails to update menu [@shamoon](https://github.com/shamoon) ([#1777](https://github.com/paperless-ngx/paperless-ngx/pull/1777)) +- Bugfix: Files containing barcodes uploaded via web are not consumed after splitting [@stumpylog](https://github.com/stumpylog) ([#1762](https://github.com/paperless-ngx/paperless-ngx/pull/1762)) +- Bugfix: Fix email labeling for non-Gmail servers [@stumpylog](https://github.com/stumpylog) ([#1755](https://github.com/paperless-ngx/paperless-ngx/pull/1755)) +- Fix: allow preview for .csv files [@shamoon](https://github.com/shamoon) ([#1744](https://github.com/paperless-ngx/paperless-ngx/pull/1744)) +- Bugfix: csv recognition by consumer [@bin101](https://github.com/bin101) ([#1726](https://github.com/paperless-ngx/paperless-ngx/pull/1726)) +- Bugfix: Include document title when a duplicate is detected [@stumpylog](https://github.com/stumpylog) ([#1696](https://github.com/paperless-ngx/paperless-ngx/pull/1696)) +- Bugfix: Set MySql charset [@stumpylog](https://github.com/stumpylog) ([#1687](https://github.com/paperless-ngx/paperless-ngx/pull/1687)) +- Mariadb compose files should use `PAPERLESS_DBPASS` [@shamoon](https://github.com/shamoon) ([#1683](https://github.com/paperless-ngx/paperless-ngx/pull/1683)) + +### Documentation + +- Documentation: Update MariaDB docs to note some potential issues [@stumpylog](https://github.com/stumpylog) ([#2016](https://github.com/paperless-ngx/paperless-ngx/pull/2016)) +- Documentation: Add note re MS exchange servers [@shamoon](https://github.com/shamoon) ([#1780](https://github.com/paperless-ngx/paperless-ngx/pull/1780)) +- Chore: Updates Gotenberg versions [@stumpylog](https://github.com/stumpylog) ([#1768](https://github.com/paperless-ngx/paperless-ngx/pull/1768)) +- Documentation: Tweak LinuxServer [@stumpylog](https://github.com/stumpylog) ([#1761](https://github.com/paperless-ngx/paperless-ngx/pull/1761)) +- Documentation: Adds troubleshooting note about Kubernetes and ports [@stumpylog](https://github.com/stumpylog) ([#1731](https://github.com/paperless-ngx/paperless-ngx/pull/1731)) +- Documentation: LinuxServer.io Migration [@stumpylog](https://github.com/stumpylog) ([#1733](https://github.com/paperless-ngx/paperless-ngx/pull/1733)) +- [Documentation] Add v1.9.2 changelog [@github-actions](https://github.com/github-actions) ([#1671](https://github.com/paperless-ngx/paperless-ngx/pull/1671)) + +### Maintenance + +- Bump tj-actions/changed-files from 32 to 34 [@dependabot](https://github.com/dependabot) ([#1915](https://github.com/paperless-ngx/paperless-ngx/pull/1915)) +- Chore: Fix `dev` trying to build Pillow or lxml [@stumpylog](https://github.com/stumpylog) ([#1909](https://github.com/paperless-ngx/paperless-ngx/pull/1909)) +- Chore: Fixes pipenv issues [@stumpylog](https://github.com/stumpylog) ([#1873](https://github.com/paperless-ngx/paperless-ngx/pull/1873)) +- Chore: Simplified registry cleanup [@stumpylog](https://github.com/stumpylog) ([#1812](https://github.com/paperless-ngx/paperless-ngx/pull/1812)) +- Chore: Fixing deprecated workflow commands [@stumpylog](https://github.com/stumpylog) ([#1786](https://github.com/paperless-ngx/paperless-ngx/pull/1786)) +- Chore: Python library update + test fixes [@stumpylog](https://github.com/stumpylog) ([#1773](https://github.com/paperless-ngx/paperless-ngx/pull/1773)) +- Chore: Updates Gotenberg versions [@stumpylog](https://github.com/stumpylog) ([#1768](https://github.com/paperless-ngx/paperless-ngx/pull/1768)) +- Bump leonsteinhaeuser/project-beta-automations from 1.3.0 to 2.0.1 [@dependabot](https://github.com/dependabot) ([#1703](https://github.com/paperless-ngx/paperless-ngx/pull/1703)) +- Bump tj-actions/changed-files from 29.0.2 to 31.0.2 [@dependabot](https://github.com/dependabot) ([#1702](https://github.com/paperless-ngx/paperless-ngx/pull/1702)) +- Bump actions/checkout from 2 to 3 [@dependabot](https://github.com/dependabot) ([#1704](https://github.com/paperless-ngx/paperless-ngx/pull/1704)) +- Bump actions/setup-python from 3 to 4 [@dependabot](https://github.com/dependabot) ([#1705](https://github.com/paperless-ngx/paperless-ngx/pull/1705)) + +### Dependencies + +
    +31 changes + +- Bugfix: Downgrade cryptography for armv7 compatibility [@stumpylog](https://github.com/stumpylog) ([#1954](https://github.com/paperless-ngx/paperless-ngx/pull/1954)) +- Chore: Bulk library updates + loosen restrictions [@stumpylog](https://github.com/stumpylog) ([#1949](https://github.com/paperless-ngx/paperless-ngx/pull/1949)) +- Bump tj-actions/changed-files from 32 to 34 [@dependabot](https://github.com/dependabot) ([#1915](https://github.com/paperless-ngx/paperless-ngx/pull/1915)) +- Bump scikit-learn from 1.1.2 to 1.1.3 [@dependabot](https://github.com/dependabot) ([#1903](https://github.com/paperless-ngx/paperless-ngx/pull/1903)) +- Bump angular packages as bundle [@dependabot](https://github.com/dependabot) ([#1910](https://github.com/paperless-ngx/paperless-ngx/pull/1910)) +- Bump ngx-ui-tour-ng-bootstrap from 11.0.0 to 11.1.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#1911](https://github.com/paperless-ngx/paperless-ngx/pull/1911)) +- Bump jest-environment-jsdom from 29.1.2 to 29.2.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#1914](https://github.com/paperless-ngx/paperless-ngx/pull/1914)) +- Bump pillow from 9.2.0 to 9.3.0 [@dependabot](https://github.com/dependabot) ([#1904](https://github.com/paperless-ngx/paperless-ngx/pull/1904)) +- Bump pytest from 7.1.3 to 7.2.0 [@dependabot](https://github.com/dependabot) ([#1902](https://github.com/paperless-ngx/paperless-ngx/pull/1902)) +- Bump tox from 3.26.0 to 3.27.0 [@dependabot](https://github.com/dependabot) ([#1901](https://github.com/paperless-ngx/paperless-ngx/pull/1901)) +- Bump zipp from 3.9.0 to 3.10.0 [@dependabot](https://github.com/dependabot) ([#1860](https://github.com/paperless-ngx/paperless-ngx/pull/1860)) +- Bump pytest-env from 0.6.2 to 0.8.1 [@dependabot](https://github.com/dependabot) ([#1859](https://github.com/paperless-ngx/paperless-ngx/pull/1859)) +- Bump sphinx from 5.2.3 to 5.3.0 [@dependabot](https://github.com/dependabot) ([#1817](https://github.com/paperless-ngx/paperless-ngx/pull/1817)) +- Chore: downgrade channels-redis [@stumpylog](https://github.com/stumpylog) ([#1802](https://github.com/paperless-ngx/paperless-ngx/pull/1802)) +- Chore: Update to qpdf 11.1.1 and update backend libraries [@stumpylog](https://github.com/stumpylog) ([#1749](https://github.com/paperless-ngx/paperless-ngx/pull/1749)) +- Bump myst-parser from 0.18.0 to 0.18.1 [@dependabot](https://github.com/dependabot) ([#1738](https://github.com/paperless-ngx/paperless-ngx/pull/1738)) +- Bump leonsteinhaeuser/project-beta-automations from 1.3.0 to 2.0.1 [@dependabot](https://github.com/dependabot) ([#1703](https://github.com/paperless-ngx/paperless-ngx/pull/1703)) +- Bump tj-actions/changed-files from 29.0.2 to 31.0.2 [@dependabot](https://github.com/dependabot) ([#1702](https://github.com/paperless-ngx/paperless-ngx/pull/1702)) +- Bump actions/checkout from 2 to 3 [@dependabot](https://github.com/dependabot) ([#1704](https://github.com/paperless-ngx/paperless-ngx/pull/1704)) +- Bump actions/setup-python from 3 to 4 [@dependabot](https://github.com/dependabot) ([#1705](https://github.com/paperless-ngx/paperless-ngx/pull/1705)) +- Bump rxjs from 7.5.6 to 7.5.7 in /src-ui [@dependabot](https://github.com/dependabot) ([#1720](https://github.com/paperless-ngx/paperless-ngx/pull/1720)) +- Bump uuid from 8.3.2 to 9.0.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#1716](https://github.com/paperless-ngx/paperless-ngx/pull/1716)) +- Bump ng2-pdf-viewer from 9.1.0 to 9.1.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#1717](https://github.com/paperless-ngx/paperless-ngx/pull/1717)) +- Bump ngx-color from 8.0.2 to 8.0.3 in /src-ui [@dependabot](https://github.com/dependabot) ([#1715](https://github.com/paperless-ngx/paperless-ngx/pull/1715)) +- Bump concurrently from 7.3.0 to 7.4.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#1719](https://github.com/paperless-ngx/paperless-ngx/pull/1719)) +- Bump [@types/node from 18.7.14 to 18.7.23 in /src-ui @dependabot](https://github.com/types/node from 18.7.14 to 18.7.23 in /src-ui @dependabot) ([#1718](https://github.com/paperless-ngx/paperless-ngx/pull/1718)) +- Bump jest-environment-jsdom from 29.0.1 to 29.1.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#1714](https://github.com/paperless-ngx/paperless-ngx/pull/1714)) +- Bump [@angular/cli @angular/core @dependabot](https://github.com/angular/cli @angular/core @dependabot) ([#1708](https://github.com/paperless-ngx/paperless-ngx/pull/1708)) +- Bump cypress from 10.7.0 to 10.9.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#1707](https://github.com/paperless-ngx/paperless-ngx/pull/1707)) +- Bump bootstrap from 5.2.0 to 5.2.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#1710](https://github.com/paperless-ngx/paperless-ngx/pull/1710)) +- Bump typescript from 4.7.4 to 4.8.4 in /src-ui [@dependabot](https://github.com/dependabot) ([#1706](https://github.com/paperless-ngx/paperless-ngx/pull/1706)) +
    + +### All App Changes + +- Add info that re-do OCR doesnt automatically refresh content [@shamoon](https://github.com/shamoon) ([#2025](https://github.com/paperless-ngx/paperless-ngx/pull/2025)) +- Bugfix: Fix created_date being a string [@stumpylog](https://github.com/stumpylog) ([#2023](https://github.com/paperless-ngx/paperless-ngx/pull/2023)) +- Bugfix: Fixes an issue with mixed text and images when redoing OCR [@stumpylog](https://github.com/stumpylog) ([#2017](https://github.com/paperless-ngx/paperless-ngx/pull/2017)) +- Bugfix: Don't allow exceptions during date parsing to fail consume [@stumpylog](https://github.com/stumpylog) ([#1998](https://github.com/paperless-ngx/paperless-ngx/pull/1998)) +- Feature: Capture stdout \& stderr of the pre/post consume scripts [@stumpylog](https://github.com/stumpylog) ([#1967](https://github.com/paperless-ngx/paperless-ngx/pull/1967)) +- Bugfix: Always re-try barcodes with pdf2image [@stumpylog](https://github.com/stumpylog) ([#1953](https://github.com/paperless-ngx/paperless-ngx/pull/1953)) +- Fix: using `CONSUMER_SUBDIRS_AS_TAGS` causes failure with Celery in `dev` [@shamoon](https://github.com/shamoon) ([#1942](https://github.com/paperless-ngx/paperless-ngx/pull/1942)) +- Fix mail consumption broken in `dev` after move to celery [@shamoon](https://github.com/shamoon) ([#1934](https://github.com/paperless-ngx/paperless-ngx/pull/1934)) +- Bugfix: Prevent file handling from running with stale data [@stumpylog](https://github.com/stumpylog) ([#1905](https://github.com/paperless-ngx/paperless-ngx/pull/1905)) +- Chore: Reduce nuisance CI test failures [@stumpylog](https://github.com/stumpylog) ([#1922](https://github.com/paperless-ngx/paperless-ngx/pull/1922)) +- Bump scikit-learn from 1.1.2 to 1.1.3 [@dependabot](https://github.com/dependabot) ([#1903](https://github.com/paperless-ngx/paperless-ngx/pull/1903)) +- Bump angular packages as bundle [@dependabot](https://github.com/dependabot) ([#1910](https://github.com/paperless-ngx/paperless-ngx/pull/1910)) +- Bump ngx-ui-tour-ng-bootstrap from 11.0.0 to 11.1.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#1911](https://github.com/paperless-ngx/paperless-ngx/pull/1911)) +- Bump jest-environment-jsdom from 29.1.2 to 29.2.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#1914](https://github.com/paperless-ngx/paperless-ngx/pull/1914)) +- Feature: Add more file name formatting options [@stumpylog](https://github.com/stumpylog) ([#1906](https://github.com/paperless-ngx/paperless-ngx/pull/1906)) +- Bump pillow from 9.2.0 to 9.3.0 [@dependabot](https://github.com/dependabot) ([#1904](https://github.com/paperless-ngx/paperless-ngx/pull/1904)) +- Bump pytest from 7.1.3 to 7.2.0 [@dependabot](https://github.com/dependabot) ([#1902](https://github.com/paperless-ngx/paperless-ngx/pull/1902)) +- Bump tox from 3.26.0 to 3.27.0 [@dependabot](https://github.com/dependabot) ([#1901](https://github.com/paperless-ngx/paperless-ngx/pull/1901)) +- directly use rapidfuzz [@maxbachmann](https://github.com/maxbachmann) ([#1899](https://github.com/paperless-ngx/paperless-ngx/pull/1899)) +- Feature: 1.9.2 UI tweaks [@shamoon](https://github.com/shamoon) ([#1886](https://github.com/paperless-ngx/paperless-ngx/pull/1886)) +- Bump zipp from 3.9.0 to 3.10.0 [@dependabot](https://github.com/dependabot) ([#1860](https://github.com/paperless-ngx/paperless-ngx/pull/1860)) +- Fix: independent control of saved views [@shamoon](https://github.com/shamoon) ([#1868](https://github.com/paperless-ngx/paperless-ngx/pull/1868)) +- Fix: frontend relative date searches [@shamoon](https://github.com/shamoon) ([#1865](https://github.com/paperless-ngx/paperless-ngx/pull/1865)) +- Django error W003 - MariaDB may not allow unique CharFields to have a max_length > 255. [@Sblop](https://github.com/Sblop) ([#1881](https://github.com/paperless-ngx/paperless-ngx/pull/1881)) +- Bump pytest-env from 0.6.2 to 0.8.1 [@dependabot](https://github.com/dependabot) ([#1859](https://github.com/paperless-ngx/paperless-ngx/pull/1859)) +- Fix: Allows configuring barcodes with pdf2image instead of pikepdf [@stumpylog](https://github.com/stumpylog) ([#1857](https://github.com/paperless-ngx/paperless-ngx/pull/1857)) +- Feature: Save pending tasks for frontend [@stumpylog](https://github.com/stumpylog) ([#1816](https://github.com/paperless-ngx/paperless-ngx/pull/1816)) +- Bugfix: Reverts the change around skip_noarchive [@stumpylog](https://github.com/stumpylog) ([#1829](https://github.com/paperless-ngx/paperless-ngx/pull/1829)) +- Bump sphinx from 5.2.3 to 5.3.0 [@dependabot](https://github.com/dependabot) ([#1817](https://github.com/paperless-ngx/paperless-ngx/pull/1817)) +- Fix: missing loadViewConfig breaks loading saved view [@shamoon](https://github.com/shamoon) ([#1792](https://github.com/paperless-ngx/paperless-ngx/pull/1792)) +- Bugfix: Fallback to pdf2image if pikepdf fails [@stumpylog](https://github.com/stumpylog) ([#1745](https://github.com/paperless-ngx/paperless-ngx/pull/1745)) +- Fix: creating new storage path on document edit fails to update menu [@shamoon](https://github.com/shamoon) ([#1777](https://github.com/paperless-ngx/paperless-ngx/pull/1777)) +- Chore: Python library update + test fixes [@stumpylog](https://github.com/stumpylog) ([#1773](https://github.com/paperless-ngx/paperless-ngx/pull/1773)) +- Feature: Improved processing for automatic matching [@stumpylog](https://github.com/stumpylog) ([#1609](https://github.com/paperless-ngx/paperless-ngx/pull/1609)) +- Feature: Transition to celery for background tasks [@stumpylog](https://github.com/stumpylog) ([#1648](https://github.com/paperless-ngx/paperless-ngx/pull/1648)) +- Feature: UI Welcome Tour [@shamoon](https://github.com/shamoon) ([#1644](https://github.com/paperless-ngx/paperless-ngx/pull/1644)) +- Feature: slim sidebar [@shamoon](https://github.com/shamoon) ([#1641](https://github.com/paperless-ngx/paperless-ngx/pull/1641)) +- Bugfix: Files containing barcodes uploaded via web are not consumed after splitting [@stumpylog](https://github.com/stumpylog) ([#1762](https://github.com/paperless-ngx/paperless-ngx/pull/1762)) +- change default matching algo to auto and move to constant [@NiFNi](https://github.com/NiFNi) ([#1754](https://github.com/paperless-ngx/paperless-ngx/pull/1754)) +- Bugfix: Fix email labeling for non-Gmail servers [@stumpylog](https://github.com/stumpylog) ([#1755](https://github.com/paperless-ngx/paperless-ngx/pull/1755)) +- Feature: frontend update checking settings [@shamoon](https://github.com/shamoon) ([#1692](https://github.com/paperless-ngx/paperless-ngx/pull/1692)) +- Fix: allow preview for .csv files [@shamoon](https://github.com/shamoon) ([#1744](https://github.com/paperless-ngx/paperless-ngx/pull/1744)) +- Bump myst-parser from 0.18.0 to 0.18.1 [@dependabot](https://github.com/dependabot) ([#1738](https://github.com/paperless-ngx/paperless-ngx/pull/1738)) +- Bugfix: csv recognition by consumer [@bin101](https://github.com/bin101) ([#1726](https://github.com/paperless-ngx/paperless-ngx/pull/1726)) +- Bugfix: Include document title when a duplicate is detected [@stumpylog](https://github.com/stumpylog) ([#1696](https://github.com/paperless-ngx/paperless-ngx/pull/1696)) +- Bump rxjs from 7.5.6 to 7.5.7 in /src-ui [@dependabot](https://github.com/dependabot) ([#1720](https://github.com/paperless-ngx/paperless-ngx/pull/1720)) +- Bump uuid from 8.3.2 to 9.0.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#1716](https://github.com/paperless-ngx/paperless-ngx/pull/1716)) +- Bump ng2-pdf-viewer from 9.1.0 to 9.1.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#1717](https://github.com/paperless-ngx/paperless-ngx/pull/1717)) +- Bump ngx-color from 8.0.2 to 8.0.3 in /src-ui [@dependabot](https://github.com/dependabot) ([#1715](https://github.com/paperless-ngx/paperless-ngx/pull/1715)) +- Bump concurrently from 7.3.0 to 7.4.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#1719](https://github.com/paperless-ngx/paperless-ngx/pull/1719)) +- Bump [@types/node from 18.7.14 to 18.7.23 in /src-ui @dependabot](https://github.com/types/node from 18.7.14 to 18.7.23 in /src-ui @dependabot) ([#1718](https://github.com/paperless-ngx/paperless-ngx/pull/1718)) +- Bump jest-environment-jsdom from 29.0.1 to 29.1.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#1714](https://github.com/paperless-ngx/paperless-ngx/pull/1714)) +- Bump [@angular/cli @angular/core @dependabot](https://github.com/angular/cli @angular/core @dependabot) ([#1708](https://github.com/paperless-ngx/paperless-ngx/pull/1708)) +- Bump cypress from 10.7.0 to 10.9.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#1707](https://github.com/paperless-ngx/paperless-ngx/pull/1707)) +- Bump bootstrap from 5.2.0 to 5.2.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#1710](https://github.com/paperless-ngx/paperless-ngx/pull/1710)) +- Bump typescript from 4.7.4 to 4.8.4 in /src-ui [@dependabot](https://github.com/dependabot) ([#1706](https://github.com/paperless-ngx/paperless-ngx/pull/1706)) +- Bugfix: Set MySql charset [@stumpylog](https://github.com/stumpylog) ([#1687](https://github.com/paperless-ngx/paperless-ngx/pull/1687)) + +## paperless-ngx 1.9.2 + +### Bug Fixes + +- Bugfix: Allow PAPERLESS_OCR_CLEAN=none [@shamoon](https://github.com/shamoon) ([#1670](https://github.com/paperless-ngx/paperless-ngx/pull/1670)) + +### All App Changes + +- Chore: Bumps version numbers to 1.9.2 [@stumpylog](https://github.com/stumpylog) ([#1666](https://github.com/paperless-ngx/paperless-ngx/pull/1666)) + ## paperless-ngx 1.9.1 +### Notes + +- Version 1.9.1 incorrectly displays the version string as 1.9.0 + ### Bug Fixes - Bugfix: Fixes missing OCR mode skip_noarchive [@stumpylog](https://github.com/stumpylog) ([#1645](https://github.com/paperless-ngx/paperless-ngx/pull/1645)) @@ -395,7 +618,7 @@ - Allow setting more than one tag in mail rules [\@jonasc](https://github.com/jonasc) ([\#270](https://github.com/paperless-ngx/paperless-ngx/pull/270)) -- Global drag\'n\'drop [\@shamoon](https://github.com/shamoon) +- Global drag'n'drop [\@shamoon](https://github.com/shamoon) ([\#283](https://github.com/paperless-ngx/paperless-ngx/pull/283)) - Fix: download buttons should disable while waiting [\@shamoon](https://github.com/shamoon) ([\#630](https://github.com/paperless-ngx/paperless-ngx/pull/630)) @@ -425,7 +648,7 @@ ### Bug Fixes -- Add \"localhost\" to ALLOWED_HOSTS +- Add "localhost" to ALLOWED_HOSTS [\@gador](https://github.com/gador) ([\#700](https://github.com/paperless-ngx/paperless-ngx/pull/700)) - Fix: scanners table [\@qcasey](https://github.com/qcasey) ([\#690](https://github.com/paperless-ngx/paperless-ngx/pull/690)) - Adds wait for file before consuming @@ -462,7 +685,7 @@ ([\#393](https://github.com/paperless-ngx/paperless-ngx/pull/393)) - Fix filterable dropdown buttons arent translated [\@shamoon](https://github.com/shamoon) ([\#366](https://github.com/paperless-ngx/paperless-ngx/pull/366)) -- Fix 224: \"Auto-detected date is day before receipt date\" +- Fix 224: "Auto-detected date is day before receipt date" [\@a17t](https://github.com/a17t) ([\#246](https://github.com/paperless-ngx/paperless-ngx/pull/246)) - Fix minor sphinx errors [\@shamoon](https://github.com/shamoon) ([\#322](https://github.com/paperless-ngx/paperless-ngx/pull/322)) @@ -524,7 +747,7 @@ This is the first release of the revived paperless-ngx project 🎉. Thank you to everyone on the paperless-ngx team for your initiative and excellent teamwork! -Version 1.6.0 merges several pending PRs from jonaswinkler\'s repo and +Version 1.6.0 merges several pending PRs from jonaswinkler's repo and includes new feature updates and bug fixes. Major backend and UI changes include: @@ -544,14 +767,14 @@ include: when document list is reloading ([jonaswinkler\#1297](https://github.com/jonaswinkler/paperless-ng/pull/1297)). - [\@shamoon](https://github.com/shamoon) improved the PDF viewer on mobile ([\#2](https://github.com/paperless-ngx/paperless-ngx/pull/2)). -- [\@shamoon](https://github.com/shamoon) added \'any\' / \'all\' and - \'not\' filtering with tags ([\#10](https://github.com/paperless-ngx/paperless-ngx/pull/10)). +- [\@shamoon](https://github.com/shamoon) added 'any' / 'all' and + 'not' filtering with tags ([\#10](https://github.com/paperless-ngx/paperless-ngx/pull/10)). - [\@shamoon](https://github.com/shamoon) added warnings for unsaved changes, with smart edit buttons ([\#13](https://github.com/paperless-ngx/paperless-ngx/pull/13)). - [\@benjaminfrank](https://github.com/benjaminfrank) enabled a non-root access to port 80 via systemd ([\#18](https://github.com/paperless-ngx/paperless-ngx/pull/18)). -- [\@tribut](https://github.com/tribut) added simple \"delete to - trash\" functionality ([\#24](https://github.com/paperless-ngx/paperless-ngx/pull/24)). See `PAPERLESS_TRASH_DIR`. +- [\@tribut](https://github.com/tribut) added simple "delete to + trash" functionality ([\#24](https://github.com/paperless-ngx/paperless-ngx/pull/24)). See `PAPERLESS_TRASH_DIR`. - [\@amenk](https://github.com/amenk) fixed the search box overlay menu on mobile ([\#32](https://github.com/paperless-ngx/paperless-ngx/pull/32)). - [\@dblitt](https://github.com/dblitt) updated the login form to not @@ -727,26 +950,22 @@ This is a maintenance release. - Changes - Firefox only: Highlight search query in PDF previews. - New URL pattern for accessing documents by ASN directly - (\/asn/123) + (/asn/123) - Added logging when executing pre\* and post-consume scripts. - Better error logging during document consumption. - Updated python dependencies. - - Automatically inserts typed text when opening \"Create new\" + - Automatically inserts typed text when opening "Create new" dialogs on the document details page. - Fixes - Fixed an issue with null characters in the document content. -::: {.note} -::: {.title} -Note -::: +!!! note The changed to the full text searching require you to reindex your -documents. _The docker image does this automatically, you don\'t need to +documents. _The docker image does this automatically, you don't need to do anything._ To do this, execute the `document_index reindex` management command (see `administration-index`{.interpreted-text role="ref"}). -::: ### paperless-ng 1.3.2 @@ -849,7 +1068,7 @@ This release contains new database migrations. worker processes of the web server. See `configuration-docker`{.interpreted-text role="ref"}. - Some more memory usage optimizations. -- Don\'t show inbox statistics if no inbox tag is defined. +- Don't show inbox statistics if no inbox tag is defined. ### paperless-ng 1.1.2 @@ -869,8 +1088,8 @@ This release contains new database migrations. This release contains new database migrations. -- Fixed a bug in the sanity checker that would cause it to display \"x - not in list\" errors instead of actual issues. +- Fixed a bug in the sanity checker that would cause it to display "x + not in list" errors instead of actual issues. - Fixed a bug with filename generation for archive filenames that would cause the archive files of two documents to overlap. - This happened when `PAPERLESS_FILENAME_FORMAT` is used and the @@ -879,8 +1098,8 @@ This release contains new database migrations. - Paperless will now store the archive filename in the database as well instead of deriving it from the original filename, and use the same logic for detecting and avoiding filename clashes - that\'s also used for original filenames. - - The migrations will repair any missing archive files. If you\'re + that's also used for original filenames. + - The migrations will repair any missing archive files. If you're using tika, ensure that tika is running while performing the migration. Docker-compose will take care of that. - Fixed a bug with thumbnail regeneration when TIKA integration was @@ -888,8 +1107,8 @@ This release contains new database migrations. - Added ASN as a placeholder field to the filename format. - The docker image now comes with built-in shortcuts for most management commands. These are now the recommended way to execute - management commands, since these also ensure that they\'re always - executed as the paperless user and you\'re less likely to run into + management commands, since these also ensure that they're always + executed as the paperless user and you're less likely to run into permission issues. See `utilities-management-commands`{.interpreted-text role="ref"}. @@ -911,10 +1130,7 @@ This release contains new database migrations. - Live updates to document lists and saved views when new documents are added. - ::: {.hint} - ::: {.title} - Hint - ::: + !!! tip For status notifications and live updates to work, paperless now requires an [ASGI](https://asgi.readthedocs.io/en/latest/)-enabled @@ -937,7 +1153,6 @@ This release contains new database migrations. Apache `mod_wsgi` users, see `this note `{.interpreted-text role="ref"}. - ::: - Paperless now offers suggestions for tags, correspondents and types on the document detail page. @@ -961,8 +1176,8 @@ This release contains new database migrations. - Better icon for document previews. - Better info section in the side bar. - Paperless no longer logs to the database. Instead, logs are - written to rotating log files. This solves many \"database is - locked\" issues on Raspberry Pi, especially when SQLite is used. + written to rotating log files. This solves many "database is + locked" issues on Raspberry Pi, especially when SQLite is used. - By default, log files are written to `PAPERLESS_DATA_DIR/log/`. Logging settings can be adjusted with `PAPERLESS_LOGGING_DIR`, `PAPERLESS_LOGROTATE_MAX_SIZE` and @@ -991,7 +1206,7 @@ bug reports coming in, I think that this is reasonably stable. - Range selection with shift clicking is now possible in the document list. - Filtering correspondent, type and tag management pages by name. - - Focus \"Name\" field in dialogs by default. + - Focus "Name" field in dialogs by default. ### paperless-ng 0.9.14 @@ -1053,8 +1268,8 @@ paperless. - Fixed an issue with filenames of downloaded files: Dates where off by one day due to timezone issues. - Searching will continue to work even when the index returns - non-existing documents. This resulted in \"Document does not - exist\" errors before. Instead, a warning is logged, indicating + non-existing documents. This resulted in "Document does not + exist" errors before. Instead, a warning is logged, indicating the issue. - An issue with the consumer crashing when invalid regular expression were used was fixed. @@ -1095,11 +1310,11 @@ paperless. new ASN to a document. - Form field validation: When providing invalid input in a form (such as a duplicate ASN or no name), paperless now has visual - indicators and clearer error messages about what\'s wrong. + indicators and clearer error messages about what's wrong. - Paperless disables buttons with network actions (such as save and delete) when a network action is active. This indicates that something is happening and prevents double clicking. - - When using \"Save & next\", the title field is focussed + - When using "Save & next", the title field is focussed automatically to better support keyboard editing. - E-Mail: Added filter rule parameters to allow inline attachments (watch out for mails with inlined images!) and attachment @@ -1108,11 +1323,11 @@ paperless. Shamoon](https://github.com/shamoon). This is useful for hiding Paperless behind single sign on applications such as [authelia](https://www.authelia.com/). - - \"Clear filters\" has been renamed to \"Reset filters\" and now + - "Clear filters" has been renamed to "Reset filters" and now correctly restores the default filters on saved views. Thanks to [Michael Shamoon](https://github.com/shamoon) - Fixes - - Paperless was unable to save views when \"Not assigned\" was + - Paperless was unable to save views when "Not assigned" was chosen in one of the filter dropdowns. - Clearer error messages when pre and post consumption scripts do not exist. @@ -1128,7 +1343,7 @@ paperless. ### paperless-ng 0.9.10 - Bulk editing - - Thanks to [Michael Shamoon](https://github.com/shamoon), we\'ve + - Thanks to [Michael Shamoon](https://github.com/shamoon), we've got a new interface for the bulk editor. - There are some configuration options in the settings to alter the behavior. @@ -1137,7 +1352,7 @@ paperless. publishes a webmanifest, which is useful for adding the application to home screens on mobile devices. - The Paperless-ng logo now navigates to the dashboard. - - Filter for documents that don\'t have any correspondents, types + - Filter for documents that don't have any correspondents, types or tags assigned. - Tags, types and correspondents are now sorted case insensitive. - Lots of preparation work for localization support. @@ -1151,10 +1366,7 @@ paperless. - The consumer used to stop working when encountering an incomplete classifier model file. -::: {.note} -::: {.title} -Note -::: +!!! note The bulk delete operations did not update the search index. Therefore, documents that you deleted remained in the index and caused the search @@ -1165,7 +1377,6 @@ However, this change is not retroactive: If you used the delete method of the bulk editor, you need to reindex your search index by `running the management command document_index with the argument reindex `{.interpreted-text role="ref"}. -::: ### paperless-ng 0.9.9 @@ -1176,18 +1387,18 @@ Christmas release! - The following operations are available: Add and remove correspondents, tags, document types from selected documents, as well as mass-deleting documents. - - We\'ve got a more fancy UI in the works that makes these - features more accessible, but that\'s not quite ready yet. + - We've got a more fancy UI in the works that makes these + features more accessible, but that's not quite ready yet. - Searching - - Paperless now supports searching for similar documents (\"More - like this\") both from the document detail page as well as from + - Paperless now supports searching for similar documents ("More + like this") both from the document detail page as well as from individual search results. - A search score indicates how well a document matches the search query, or how similar a document is to a given reference document. - Other additions and changes - - Clarification in the UI that the fields \"Match\" and \"Is - insensitive\" are not relevant for the Auto matching algorithm. + - Clarification in the UI that the fields "Match" and "Is + insensitive" are not relevant for the Auto matching algorithm. - New select interface for tags, types and correspondents allows filtering. This also improves tag selection. Thanks again to [Michael Shamoon](https://github.com/shamoon)! @@ -1268,11 +1479,11 @@ This release focusses primarily on many small issues with the UI. - Paperless now has proper window titles. - Fixed an issue with the small cards when more than 7 tags were used. - - Navigation of the \"Show all\" links adjusted. They navigate to + - Navigation of the "Show all" links adjusted. They navigate to the saved view now, if available in the sidebar. - Some indication on the document lists that a filter is active was added. - - There\'s a new filter to filter for documents that do _not_ have + - There's a new filter to filter for documents that do _not_ have a certain tag. - The file upload box now shows upload progress. - The document edit page was reorganized. @@ -1297,15 +1508,11 @@ This release focusses primarily on many small issues with the UI. filenames anymore. It will rather append `_01`, `_02`, etc when it detects duplicate filenames. -::: {.note} -::: {.title} -Note -::: +!!! note The changes to the filename format will apply to newly added documents and changed documents. If you want all files to reflect these changes, execute the `document_renamer` management command. -::: ### paperless-ng 0.9.5 @@ -1388,7 +1595,7 @@ primarily. need to do this once, since the schema of the search index changed. Paperless keeps the index updated after that whenever something changes. - - Paperless now has spelling corrections (\"Did you mean\") for + - Paperless now has spelling corrections ("Did you mean") for miss-typed queries. - The documentation contains `information about the query syntax `{.interpreted-text @@ -1458,7 +1665,7 @@ primarily. role="ref"} This features will most likely be removed in future versions. - **Added:** New frontend. Features: - - Single page application: It\'s much more responsive than the + - Single page application: It's much more responsive than the django admin pages. - Dashboard. Shows recently scanned documents, or todo notes, or other documents at wish. Allows uploading of documents. Shows @@ -1480,7 +1687,7 @@ primarily. - **Added:** Archive serial numbers. Assign these to quickly find documents stored in physical binders. - **Added:** Enabled the internal user management of django. This - isn\'t really a multi user solution, however, it allows more than + isn't really a multi user solution, however, it allows more than one user to access the website and set some basic permissions / renew passwords. - **Modified \[breaking\]:** All new mail consumer with customizable @@ -1535,7 +1742,7 @@ primarily. - **Settings:** - `PAPERLESS_FORGIVING_OCR` is now default and gone. Reason: Even if `langdetect` fails to detect a language, tesseract still does - a very good job at ocr\'ing a document with the default + a very good job at ocr'ing a document with the default language. Certain language specifics such as umlauts may not get picked up properly. - `PAPERLESS_DEBUG` defaults to `false`. @@ -1616,34 +1823,34 @@ primarily. [\#442](https://github.com/the-paperless-project/paperless/pull/442). - Added a `.editorconfig` file to better specify coding style. - [Joshua Taillon](https://github.com/jat255) also added some logic to - tie Paperless\' date guessing logic into how it parses file names on + tie Paperless' date guessing logic into how it parses file names on import. [\#440](https://github.com/the-paperless-project/paperless/pull/440) ### 2.5.0 - **New dependency**: Paperless now optimises thumbnail generation - with [optipng](http://optipng.sourceforge.net/), so you\'ll need to + with [optipng](http://optipng.sourceforge.net/), so you'll need to install that somewhere in your PATH or declare its location in `PAPERLESS_OPTIPNG_BINARY`. The Docker image has already been updated on the Docker Hub, so you just need to pull the latest one - from there if you\'re a Docker user. -- \"Login free\" instances of Paperless were breaking whenever you + from there if you're a Docker user. +- "Login free" instances of Paperless were breaking whenever you tried to edit objects in the admin: adding/deleting tags or - correspondents, or even fixing spelling. This was due to the \"user - hack\" we were applying to sessions that weren\'t using a login, as - that hack user didn\'t have a valid id. The fix was to attribute the + correspondents, or even fixing spelling. This was due to the "user + hack" we were applying to sessions that weren't using a login, as + that hack user didn't have a valid id. The fix was to attribute the first user id in the system to this hack user. [\#394](https://github.com/the-paperless-project/paperless/issues/394) - A problem in how we handle slug values on Tags and Correspondents required a few changes to how we handle this field [\#393](https://github.com/the-paperless-project/paperless/issues/393): - 1. Slugs are no longer editable. They\'re derived from the name of + 1. Slugs are no longer editable. They're derived from the name of the tag or correspondent at save time, so if you wanna change - the slug, you have to change the name, and even then you\'re + the slug, you have to change the name, and even then you're restricted to the rules of the `slugify()` function. The slug value is still visible in the admin though. - 2. I\'ve added a migration to go over all existing tags & + 2. I've added a migration to go over all existing tags & correspondents and rewrite the `.slug` values to ones conforming to the `slugify()` rules. 3. The consumption process now uses the same rules as `.save()` in @@ -1654,7 +1861,7 @@ primarily. Thanks to [Andrew Peng](https://github.com/pengc99) for reporting this. [\#414](https://github.com/the-paperless-project/paperless/issues/414). -- A bug in the Dockerfile meant that Tesseract language files weren\'t +- A bug in the Dockerfile meant that Tesseract language files weren't being installed correctly. [euri10](https://github.com/euri10) was quick to provide a fix: [\#406](https://github.com/the-paperless-project/paperless/issues/406), @@ -1669,13 +1876,13 @@ primarily. ### 2.4.0 - A new set of actions are now available thanks to - [jonaswinkler](https://github.com/jonaswinkler)\'s very first pull + [jonaswinkler](https://github.com/jonaswinkler)'s very first pull request! You can now do nifty things like tag documents in bulk, or set correspondents in bulk. [\#405](https://github.com/the-paperless-project/paperless/pull/405) - The import/export system is now a little smarter. By default, documents are tagged as `unencrypted`, since exports are by their - nature unencrypted. It\'s now in the import step that we decide the + nature unencrypted. It's now in the import step that we decide the storage type. This allows you to export from an encrypted system and import into an unencrypted one, or vice-versa. - The migration history has been slightly modified to accommodate @@ -1693,7 +1900,7 @@ primarily. - Support for consuming plain text & markdown documents was added by [Joshua Taillon](https://github.com/jat255)! This was a - long-requested feature, and it\'s addition is likely to be greatly + long-requested feature, and it's addition is likely to be greatly appreciated by the community: [\#395](https://github.com/the-paperless-project/paperless/pull/395) Thanks also to [David Martin](https://github.com/ddddavidmartin) for @@ -1734,7 +1941,7 @@ primarily. lots of different tags: [\#391](https://github.com/the-paperless-project/paperless/pull/391). - [Kilian Koeltzsch](https://github.com/kiliankoe) noticed a bug in - how we capture & automatically create tags, so that\'s fixed now + how we capture & automatically create tags, so that's fixed now too: [\#384](https://github.com/the-paperless-project/paperless/issues/384). - [erikarvstedt](https://github.com/erikarvstedt) tweaked the @@ -1750,7 +1957,7 @@ primarily. - [Enno Lohmeier](https://github.com/elohmeier) added three simple features that make Paperless a lot more user (and developer) friendly: - 1. There\'s a new search box on the front page: + 1. There's a new search box on the front page: [\#374](https://github.com/the-paperless-project/paperless/pull/374). 2. The correspondents & tags pages now have a column showing the number of relevant documents: @@ -1760,18 +1967,18 @@ primarily. environment: [\#376](https://github.com/the-paperless-project/paperless/pull/376). - You now also have the ability to customise the interface to your - heart\'s content by creating a file called `overrides.css` and/or + heart's content by creating a file called `overrides.css` and/or `overrides.js` in the root of your media directory. Thanks to [Mark McFate](https://github.com/SummittDweller) for this idea: [\#371](https://github.com/the-paperless-project/paperless/issues/371) ### 2.0.0 -This is a big release as we\'ve changed a core-functionality of +This is a big release as we've changed a core-functionality of Paperless: we no longer encrypt files with GPG by default. The reasons for this are many, but it boils down to that the encryption -wasn\'t really all that useful, as files on-disk were still accessible +wasn't really all that useful, as files on-disk were still accessible so long as you had the key, and the key was most typically stored in the config file. In other words, your files are only as safe as the `paperless` user is. In addition to that, _the contents of the documents @@ -1783,7 +1990,7 @@ explicitly set a passphrase in your config file. ### Migrating from 1.x -Encryption isn\'t gone, it\'s just off for new users. So long as you +Encryption isn't gone, it's just off for new users. So long as you have `PAPERLESS_PASSPHRASE` set in your config or your environment, Paperless should continue to operate as it always has. If however, you want to drop encryption too, you only need to do two things: @@ -1813,7 +2020,7 @@ this big change. for more information. - Refactor the use of travis/tox/pytest/coverage into two files: `.travis.yml` and `setup.cfg`. -- Start generating requirements.txt from a Pipfile. I\'ll probably +- Start generating requirements.txt from a Pipfile. I'll probably switch over to just using pipenv in the future. - All for a alternative FreeBSD-friendly location for `paperless.conf`. Thanks to [Martin @@ -1833,7 +2040,7 @@ this big change. [\#253](https://github.com/the-paperless-project/paperless/issues/253) and [\#323](https://github.com/the-paperless-project/paperless/issues/323), - we\'ve removed a few of the hardcoded URL values to make it easier + we've removed a few of the hardcoded URL values to make it easier for people to host Paperless on a subdirectory. Thanks to [Quentin Dawans](https://github.com/ovv) and [Kyle Lucy](https://github.com/kmlucy) for helping to work this out. @@ -1846,7 +2053,7 @@ this big change. very creating Bash skills: [\#352](https://github.com/the-paperless-project/paperless/pull/352). - You can now use the search field to find documents by tag thanks to - [thinkjk](https://github.com/thinkjk)\'s _first ever issue_: + [thinkjk](https://github.com/thinkjk)'s _first ever issue_: [\#354](https://github.com/the-paperless-project/paperless/issues/354). - Inotify is now being used to detect additions to the consume directory thanks to some excellent work from @@ -1855,7 +2062,7 @@ this big change. ### 1.3.0 -- You can now run Paperless without a login, though you\'ll still have +- You can now run Paperless without a login, though you'll still have to create at least one user. This is thanks to a pull-request from [matthewmoto](https://github.com/matthewmoto): [\#295](https://github.com/the-paperless-project/paperless/pull/295). @@ -1886,7 +2093,7 @@ this big change. [\#312](https://github.com/the-paperless-project/paperless/pull/312) to fix [\#306](https://github.com/the-paperless-project/paperless/issues/306). -- Patch the historical migrations to support MySQL\'s um, +- Patch the historical migrations to support MySQL's um, _interesting_ way of handing indexes ([\#308](https://github.com/the-paperless-project/paperless/issues/308)). Thanks to [Simon Taddiken](https://github.com/skuzzle) for reporting @@ -1908,7 +2115,7 @@ this big change. already contains text. This can be overridden by setting `PAPERLESS_OCR_ALWAYS=YES` either in your `paperless.conf` or in the environment. Note that this also means that Paperless now requires - `libpoppler-cpp-dev` to be installed. **Important**: You\'ll need to + `libpoppler-cpp-dev` to be installed. **Important**: You'll need to run `pip install -r requirements.txt` after the usual `git pull` to properly update. - [BastianPoe](https://github.com/BastianPoe) has also contributed a @@ -1935,7 +2142,7 @@ this big change. ### 1.0.0 -- Upgrade to Django 1.11. **You\'ll need to run \`\`pip install -r +- Upgrade to Django 1.11. **You'll need to run \`\`pip install -r requirements.txt\`\` after the usual \`\`git pull\`\` to properly update**. - Replace the templatetag-based hack we had for document listing in @@ -1956,14 +2163,14 @@ this big change. [Pit](https://github.com/pitkley) on [\#268](https://github.com/the-paperless-project/paperless/pull/268). - Date fields in the admin are now expressed as HTML5 date fields - thanks to [Lukas Winkler](https://github.com/Findus23)\'s issue + thanks to [Lukas Winkler](https://github.com/Findus23)'s issue [\#278](https://github.com/the-paperless-project/paperless/issues/248) ### 0.8.0 - Paperless can now run in a subdirectory on a host (`/paperless`), rather than always running in the root (`/`) thanks to - [maphy-psd](https://github.com/maphy-psd)\'s work on + [maphy-psd](https://github.com/maphy-psd)'s work on [\#255](https://github.com/the-paperless-project/paperless/pull/255). ### 0.7.0 @@ -1972,14 +2179,14 @@ this big change. [\#235](https://github.com/the-paperless-project/paperless/issues/235), Paperless will no longer automatically delete documents attached to correspondents when those correspondents are themselves deleted. - This was Django\'s default behaviour, but didn\'t make much sense in - Paperless\' case. Thanks to [Thomas + This was Django's default behaviour, but didn't make much sense in + Paperless' case. Thanks to [Thomas Brueggemann](https://github.com/thomasbrueggemann) and [David Martin](https://github.com/ddddavidmartin) for their input on this one. - Fix for [\#232](https://github.com/the-paperless-project/paperless/issues/232) - wherein Paperless wasn\'t recognising `.tif` files properly. Thanks + wherein Paperless wasn't recognising `.tif` files properly. Thanks to [ayounggun](https://github.com/ayounggun) for reporting this one and to [Kusti Skytén](https://github.com/kskyten) for posting the correct solution in the Github issue. @@ -1990,12 +2197,12 @@ this big change. favour of BasicAuth or Django session. - Fix the POST API so it actually works. [\#236](https://github.com/the-paperless-project/paperless/issues/236) -- **Breaking change**: We\'ve dropped the use of +- **Breaking change**: We've dropped the use of `PAPERLESS_SHARED_SECRET` as it was being used both for the API (now - replaced with a normal auth) and form email polling. Now that we\'re + replaced with a normal auth) and form email polling. Now that we're only using it for email, this variable has been renamed to `PAPERLESS_EMAIL_SECRET`. The old value will still work for a while, - but you should change your config if you\'ve been using the email + but you should change your config if you've been using the email polling feature. Thanks to [Joshua Gilman](https://github.com/jmgilman) for all the help with this feature. @@ -2003,7 +2210,7 @@ this big change. ### 0.5.0 - Support for fuzzy matching in the auto-tagger & auto-correspondent - systems thanks to [Jake Gysland](https://github.com/jgysland)\'s + systems thanks to [Jake Gysland](https://github.com/jgysland)'s patch [\#220](https://github.com/the-paperless-project/paperless/pull/220). - Modified the Dockerfile to prepare an export directory @@ -2032,7 +2239,7 @@ this big change. - Fix for [\#206](https://github.com/the-paperless-project/paperless/issues/206) - wherein the pluggable parser didn\'t recognise files with all-caps + wherein the pluggable parser didn't recognise files with all-caps suffixes like `.PDF` ### 0.4.0 @@ -2042,7 +2249,7 @@ this big change. for more information, but the short explanation is that you can now attach simple notes & times to documents which are made available via the API. Currently, the default API (basically just the Django - admin) doesn\'t really make use of this, but [Thomas + admin) doesn't really make use of this, but [Thomas Brueggemann](https://github.com/thomasbrueggemann) over at [Paperless Desktop](https://github.com/thomasbrueggemann/paperless-desktop) has @@ -2052,16 +2259,16 @@ this big change. - Fix for [\#200](https://github.com/the-paperless-project/paperless/issues/200) - (!!) where the API wasn\'t configured to allow updating the + (!!) where the API wasn't configured to allow updating the correspondent or the tags for a document. - The `content` field is now optional, to allow for the edge case of a purely graphical document. - You can no longer add documents via the admin. This never worked in - the first place, so all I\'ve done here is remove the link to the + the first place, so all I've done here is remove the link to the broken form. - The consumer code has been heavily refactored to support a pluggable interface. Install a paperless consumer via pip and tell paperless - about it with an environment variable, and you\'re good to go. + about it with an environment variable, and you're good to go. Proper documentation is on its way. ### 0.3.5 @@ -2082,10 +2289,10 @@ this big change. - Removal of django-suit due to a licensing conflict I bumped into in 0.3.3. Note that you _can_ use Django Suit with Paperless, but only in a non-profit situation as their free license prohibits for-profit - use. As a result, I can\'t bundle Suit with Paperless without + use. As a result, I can't bundle Suit with Paperless without conflicting with the GPL. Further development will be done against the stock Django admin. -- I shrunk the thumbnails a little \'cause they were too big for me, +- I shrunk the thumbnails a little 'cause they were too big for me, even on my high-DPI monitor. - BasicAuth support for document and thumbnail downloads, as well as the Push API thanks to \@thomasbrueggemann. See @@ -2112,14 +2319,14 @@ this big change. ### 0.3.0 - Updated to using django-filter 1.x -- Added some system checks so new users aren\'t confused by +- Added some system checks so new users aren't confused by misconfigurations. - Consumer loop time is now configurable for systems with slow writes. Just set `PAPERLESS_CONSUMER_LOOP_TIME` to a number of seconds. The default is 10. - As per [\#44](https://github.com/the-paperless-project/paperless/issues/44), - we\'ve removed support for `PAPERLESS_CONVERT`, `PAPERLESS_CONSUME`, + we've removed support for `PAPERLESS_CONVERT`, `PAPERLESS_CONSUME`, and `PAPERLESS_SECRET`. Please use `PAPERLESS_CONVERT_BINARY`, `PAPERLESS_CONSUMPTION_DIR`, and `PAPERLESS_SHARED_SECRET` respectively instead. @@ -2134,17 +2341,17 @@ this big change. - [\#146](https://github.com/the-paperless-project/paperless/issues/146): Fixed a bug that allowed unauthorised access to the `/fetch` URL. - [\#131](https://github.com/the-paperless-project/paperless/issues/131): - Document files are now automatically removed from disk when they\'re + Document files are now automatically removed from disk when they're deleted in Paperless. - [\#121](https://github.com/the-paperless-project/paperless/issues/121): - Fixed a bug where Paperless wasn\'t setting document creation time + Fixed a bug where Paperless wasn't setting document creation time based on the file naming scheme. - [\#81](https://github.com/the-paperless-project/paperless/issues/81): Added a hook to run an arbitrary script after every document is consumed. - [\#98](https://github.com/the-paperless-project/paperless/issues/98): Added optional environment variables for ImageMagick so that it - doesn\'t explode when handling Very Large Documents or when it\'s + doesn't explode when handling Very Large Documents or when it's just running on a low-memory system. Thanks to [Florian Harr](https://github.com/evils) for his help on this one. - [\#89](https://github.com/the-paperless-project/paperless/issues/89) @@ -2163,8 +2370,8 @@ this big change. ### 0.1.1 -- Potentially **Breaking Change**: All references to \"sender\" in the - code have been renamed to \"correspondent\" to better reflect the +- Potentially **Breaking Change**: All references to "sender" in the + code have been renamed to "correspondent" to better reflect the nature of the property (one could quite reasonably scan a document before sending it to someone.) - [\#67](https://github.com/the-paperless-project/paperless/issues/67): @@ -2178,7 +2385,7 @@ this big change. contributing conversation that lead to this change. - [\#20](https://github.com/the-paperless-project/paperless/issues/20): Added _unpaper_ support to help in cleaning up the scanned image - before it\'s OCR\'d. Thanks to [Pit](https://github.com/pitkley) for + before it's OCR'd. Thanks to [Pit](https://github.com/pitkley) for this one. - [\#71](https://github.com/the-paperless-project/paperless/issues/71) Added (encrypted) thumbnails in anticipation of a proper UI. diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 096ccc1af..000000000 --- a/docs/conf.py +++ /dev/null @@ -1,337 +0,0 @@ -import sphinx_rtd_theme - - -__version__ = None -__full_version_str__ = None -__major_minor_version_str__ = None -exec(open("../src/paperless/version.py").read()) - - -extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.intersphinx", - "sphinx.ext.todo", - "sphinx.ext.imgmath", - "sphinx.ext.viewcode", - "sphinx_rtd_theme", - "myst_parser", -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix of source filenames. -source_suffix = { - ".rst": "restructuredtext", - ".md": "markdown", -} - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = "index" - -# General information about the project. -project = "Paperless-ngx" -copyright = "2015-2022, Daniel Quinn, Jonas Winkler, and the paperless-ngx team" - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# - -# -# If the build process ever explodes here, it's because you've set the version -# number in paperless.version to a tuple with 3 numbers in it. -# - -# The short X.Y version. -version = __major_minor_version_str__ -# The full version, including alpha/beta/rc tags. -release = __full_version_str__ - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ["_build"] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = "sphinx_rtd_theme" - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# These paths are either relative to html_static_path -# or fully qualified paths (eg. https://...) -html_css_files = [ - "css/custom.css", -] - -html_js_files = [ - "js/darkmode.js", -] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = "paperless" - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - #'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ("index", "paperless.tex", "Paperless Documentation", "Daniel Quinn", "manual"), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [("index", "paperless", "Paperless Documentation", ["Daniel Quinn"], 1)] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - "index", - "Paperless", - "Paperless Documentation", - "Daniel Quinn", - "paperless", - "Scan, index, and archive all of your paper documents.", - "Miscellaneous", - ), -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False - - -# -- Options for Epub output ---------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = "Paperless" -epub_author = "Daniel Quinn" -epub_publisher = "Daniel Quinn" -epub_copyright = "2015, Daniel Quinn" - -# The basename for the epub file. It defaults to the project name. -# epub_basename = u'Paperless' - -# The HTML theme for the epub output. Since the default themes are not optimized -# for small screen space, using the same theme for HTML and epub output is -# usually not wise. This defaults to 'epub', a theme designed to save visual -# space. -# epub_theme = 'epub' - -# The language of the text. It defaults to the language option -# or en if the language is not set. -# epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -# epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# epub_identifier = '' - -# A unique identification for the text. -# epub_uid = '' - -# A tuple containing the cover image and cover page html template filenames. -# epub_cover = () - -# A sequence of (type, uri, title) tuples for the guide element of content.opf. -# epub_guide = () - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# epub_pre_files = [] - -# HTML files shat should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# epub_post_files = [] - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ["search.html"] - -# The depth of the table of contents in toc.ncx. -# epub_tocdepth = 3 - -# Allow duplicate toc entries. -# epub_tocdup = True - -# Choose between 'default' and 'includehidden'. -# epub_tocscope = 'default' - -# Fix unsupported image types using the PIL. -# epub_fix_images = False - -# Scale large images. -# epub_max_image_width = 0 - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# epub_show_urls = 'inline' - -# If false, no index is generated. -# epub_use_index = True - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {"http://docs.python.org/": None} diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 000000000..bcde72e5f --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,1036 @@ +# Configuration + +Paperless provides a wide range of customizations. Depending on how you +run paperless, these settings have to be defined in different places. + +- If you run paperless on docker, `paperless.conf` is not used. + Rather, configure paperless by copying necessary options to + `docker-compose.env`. + +- If you are running paperless on anything else, paperless will search + for the configuration file in these locations and use the first one + it finds: + + ``` + /path/to/paperless/paperless.conf + /etc/paperless.conf + /usr/local/etc/paperless.conf + ``` + +## Required services + +`PAPERLESS_REDIS=` + +: This is required for processing scheduled tasks such as email +fetching, index optimization and for training the automatic document +matcher. + + - If your Redis server needs login credentials PAPERLESS_REDIS = + `redis://:@:` + - With the requirepass option PAPERLESS_REDIS = + `redis://:@:` + + [More information on securing your Redis + Instance](https://redis.io/docs/getting-started/#securing-redis). + + Defaults to . + +`PAPERLESS_DBENGINE=` + +: Optional, gives the ability to choose Postgres or MariaDB for +database engine. Available options are [postgresql]{.title-ref} and +[mariadb]{.title-ref}. + + Default is [postgresql]{.title-ref}. + + !!! warning + + Using MariaDB comes with some caveats. See [MySQL Caveats](advanced_usage#mysql-caveats). + +`PAPERLESS_DBHOST=` + +: By default, sqlite is used as the database backend. This can be +changed here. + + Set PAPERLESS_DBHOST and another database will be used instead of + sqlite. + +`PAPERLESS_DBPORT=` + +: Adjust port if necessary. + + Default is 5432. + +`PAPERLESS_DBNAME=` + +: Database name in PostgreSQL or MariaDB. + + Defaults to "paperless". + +`PAPERLESS_DBUSER=` + +: Database user in PostgreSQL or MariaDB. + + Defaults to "paperless". + +`PAPERLESS_DBPASS=` + +: Database password for PostgreSQL or MariaDB. + + Defaults to "paperless". + +`PAPERLESS_DBSSLMODE=` + +: SSL mode to use when connecting to PostgreSQL. + + See [the official documentation about + sslmode](https://www.postgresql.org/docs/current/libpq-ssl.html). + + Default is `prefer`. + +`PAPERLESS_DB_TIMEOUT=` + +: Amount of time for a database connection to wait for the database to +unlock. Mostly applicable for an sqlite based installation, consider +changing to postgresql if you need to increase this. + + Defaults to unset, keeping the Django defaults. + +## Paths and folders + +`PAPERLESS_CONSUMPTION_DIR=` + +: This where your documents should go to be consumed. Make sure that +it exists and that the user running the paperless service can +read/write its contents before you start Paperless. + + Don't change this when using docker, as it only changes the path + within the container. Change the local consumption directory in the + docker-compose.yml file instead. + + Defaults to "../consume/", relative to the "src" directory. + +`PAPERLESS_DATA_DIR=` + +: This is where paperless stores all its data (search index, SQLite +database, classification model, etc). + + Defaults to "../data/", relative to the "src" directory. + +`PAPERLESS_TRASH_DIR=` + +: Instead of removing deleted documents, they are moved to this +directory. + + This must be writeable by the user running paperless. When running + inside docker, ensure that this path is within a permanent volume + (such as "../media/trash") so it won't get lost on upgrades. + + Defaults to empty (i.e. really delete documents). + +`PAPERLESS_MEDIA_ROOT=` + +: This is where your documents and thumbnails are stored. + + You can set this and PAPERLESS_DATA_DIR to the same folder to have + paperless store all its data within the same volume. + + Defaults to "../media/", relative to the "src" directory. + +`PAPERLESS_STATICDIR=` + +: Override the default STATIC_ROOT here. This is where all static +files created using "collectstatic" manager command are stored. + + Unless you're doing something fancy, there is no need to override + this. + + Defaults to "../static/", relative to the "src" directory. + +`PAPERLESS_FILENAME_FORMAT=` + +: Changes the filenames paperless uses to store documents in the media +directory. See [File name handling](advanced_usage#file_name_handling) for details. + + Default is none, which disables this feature. + +`PAPERLESS_FILENAME_FORMAT_REMOVE_NONE=` + +: Tells paperless to replace placeholders in +[PAPERLESS_FILENAME_FORMAT]{.title-ref} that would resolve to +'none' to be omitted from the resulting filename. This also holds +true for directory names. See [File name handling](advanced_usage#file_name_handling) for +details. + + Defaults to [false]{.title-ref} which disables this feature. + +`PAPERLESS_LOGGING_DIR=` + +: This is where paperless will store log files. + + Defaults to "`PAPERLESS_DATA_DIR`/log/". + +## Logging + +`PAPERLESS_LOGROTATE_MAX_SIZE=` + +: Maximum file size for log files before they are rotated, in bytes. + + Defaults to 1 MiB. + +`PAPERLESS_LOGROTATE_MAX_BACKUPS=` + +: Number of rotated log files to keep. + + Defaults to 20. + +## Hosting & Security {#hosting-and-security} + +`PAPERLESS_SECRET_KEY=` + +: Paperless uses this to make session tokens. If you expose paperless +on the internet, you need to change this, since the default secret +is well known. + + Use any sequence of characters. The more, the better. You don't + need to remember this. Just face-roll your keyboard. + + Default is listed in the file `src/paperless/settings.py`. + +`PAPERLESS_URL=` + +: This setting can be used to set the three options below +(ALLOWED_HOSTS, CORS_ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS). If the +other options are set the values will be combined with this one. Do +not include a trailing slash. E.g. + + Defaults to empty string, leaving the other settings unaffected. + +`PAPERLESS_CSRF_TRUSTED_ORIGINS=` + +: A list of trusted origins for unsafe requests (e.g. POST). As of +Django 4.0 this is required to access the Django admin via the web. +See + + + Can also be set using PAPERLESS_URL (see above). + + Defaults to empty string, which does not add any origins to the + trusted list. + +`PAPERLESS_ALLOWED_HOSTS=` + +: If you're planning on putting Paperless on the open internet, then +you really should set this value to the domain name you're using. +Failing to do so leaves you open to HTTP host header attacks: + + + Just remember that this is a comma-separated list, so + "example.com" is fine, as is "example.com,www.example.com", but + NOT " example.com" or "example.com," + + Can also be set using PAPERLESS_URL (see above). + + If manually set, please remember to include "localhost". Otherwise + docker healthcheck will fail. + + Defaults to "\*", which is all hosts. + +`PAPERLESS_CORS_ALLOWED_HOSTS=` + +: You need to add your servers to the list of allowed hosts that can +do CORS calls. Set this to your public domain name. + + Can also be set using PAPERLESS_URL (see above). + + Defaults to "". + +`PAPERLESS_FORCE_SCRIPT_NAME=` + +: To host paperless under a subpath url like example.com/paperless you +set this value to /paperless. No trailing slash! + + Defaults to none, which hosts paperless at "/". + +`PAPERLESS_STATIC_URL=` + +: Override the STATIC_URL here. Unless you're hosting Paperless off a +subdomain like /paperless/, you probably don't need to change this. +If you do change it, be sure to include the trailing slash. + + Defaults to "/static/". + + !!! note + + When hosting paperless behind a reverse proxy like Traefik or Nginx + at a subpath e.g. example.com/paperlessngx you will also need to set + `PAPERLESS_FORCE_SCRIPT_NAME` (see above). + +`PAPERLESS_AUTO_LOGIN_USERNAME=` + +: Specify a username here so that paperless will automatically perform +login with the selected user. + + !!! danger + + Do not use this when exposing paperless on the internet. There are + no checks in place that would prevent you from doing this. + + Defaults to none, which disables this feature. + +`PAPERLESS_ADMIN_USER=` + +: If this environment variable is specified, Paperless automatically +creates a superuser with the provided username at start. This is +useful in cases where you can not run the +[createsuperuser]{.title-ref} command separately, such as Kubernetes +or AWS ECS. + + Requires [PAPERLESS_ADMIN_PASSWORD]{.title-ref} to be set. + + !!! note + + This will not change an existing \[super\]user's password, nor will + it recreate a user that already exists. You can leave this + throughout the lifecycle of the containers. + +`PAPERLESS_ADMIN_MAIL=` + +: (Optional) Specify superuser email address. Only used when +[PAPERLESS_ADMIN_USER]{.title-ref} is set. + + Defaults to `root@localhost`. + +`PAPERLESS_ADMIN_PASSWORD=` + +: Only used when [PAPERLESS_ADMIN_USER]{.title-ref} is set. This will +be the password of the automatically created superuser. + +`PAPERLESS_COOKIE_PREFIX=` + +: Specify a prefix that is added to the cookies used by paperless to +identify the currently logged in user. This is useful for when +you're running two instances of paperless on the same host. + + After changing this, you will have to login again. + + Defaults to `""`, which does not alter the cookie names. + +`PAPERLESS_ENABLE_HTTP_REMOTE_USER=` + +: Allows authentication via HTTP_REMOTE_USER which is used by some SSO +applications. + + !!! warning + + This will allow authentication by simply adding a + `Remote-User: ` header to a request. Use with care! You + especially *must: ensure that any such header is not passed from + your proxy server to paperless. + + If you're exposing paperless to the internet directly, do not use + this. + + Also see the warning [in the official documentation + ]{.title-ref}. + + Defaults to [false]{.title-ref} which disables this feature. + +`PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME=` + +: If [PAPERLESS_ENABLE_HTTP_REMOTE_USER]{.title-ref} is enabled, this +property allows to customize the name of the HTTP header from which +the authenticated username is extracted. Values are in terms of +\[HttpRequest.META\](). +Thus, the configured value must start with [HTTP\_]{.title-ref} +followed by the normalized actual header name. + + Defaults to [HTTP_REMOTE_USER]{.title-ref}. + +`PAPERLESS_LOGOUT_REDIRECT_URL=` + +: URL to redirect the user to after a logout. This can be used +together with [PAPERLESS_ENABLE_HTTP_REMOTE_USER]{.title-ref} to +redirect the user back to the SSO application's logout page. + + Defaults to None, which disables this feature. + +## OCR settings {#ocr} + +Paperless uses [OCRmyPDF](https://ocrmypdf.readthedocs.io/en/latest/) +for performing OCR on documents and images. Paperless uses sensible +defaults for most settings, but all of them can be configured to your +needs. + +`PAPERLESS_OCR_LANGUAGE=` + +: Customize the language that paperless will attempt to use when +parsing documents. + + It should be a 3-letter language code consistent with ISO 639: + + + Set this to the language most of your documents are written in. + + This can be a combination of multiple languages such as `deu+eng`, + in which case tesseract will use whatever language matches best. + Keep in mind that tesseract uses much more cpu time with multiple + languages enabled. + + Defaults to "eng". + + !!! note + + If your language contains a '-' such as chi-sim, you must use chi_sim + +`PAPERLESS_OCR_MODE=` + +: Tell paperless when and how to perform ocr on your documents. Four +modes are available: + + - `skip`: Paperless skips all pages and will perform ocr only on + pages where no text is present. This is the safest option. + + - `skip_noarchive`: In addition to skip, paperless won't create + an archived version of your documents when it finds any text in + them. This is useful if you don't want to have two + almost-identical versions of your digital documents in the media + folder. This is the fastest option. + + - `redo`: Paperless will OCR all pages of your documents and + attempt to replace any existing text layers with new text. This + will be useful for documents from scanners that already + performed OCR with insufficient results. It will also perform + OCR on purely digital documents. + + This option may fail on some documents that have features that + cannot be removed, such as forms. In this case, the text from + the document is used instead. + + - `force`: Paperless rasterizes your documents, converting any + text into images and puts the OCRed text on top. This works for + all documents, however, the resulting document may be + significantly larger and text won't appear as sharp when zoomed + in. + + The default is `skip`, which only performs OCR when necessary and + always creates archived documents. + + Read more about this in the [OCRmyPDF + documentation](https://ocrmypdf.readthedocs.io/en/latest/advanced.html#when-ocr-is-skipped). + +`PAPERLESS_OCR_CLEAN=` + +: Tells paperless to use `unpaper` to clean any input document before +sending it to tesseract. This uses more resources, but generally +results in better OCR results. The following modes are available: + + - `clean`: Apply unpaper. + - `clean-final`: Apply unpaper, and use the cleaned images to + build the output file instead of the original images. + - `none`: Do not apply unpaper. + + Defaults to `clean`. + + !!! note + + `clean-final` is incompatible with ocr mode `redo`. When both + `clean-final` and the ocr mode `redo` is configured, `clean` is used + instead. + +`PAPERLESS_OCR_DESKEW=` + +: Tells paperless to correct skewing (slight rotation of input images +mainly due to improper scanning) + + Defaults to `true`, which enables this feature. + + !!! note + + Deskewing is incompatible with ocr mode `redo`. Deskewing will get + disabled automatically if `redo` is used as the ocr mode. + +`PAPERLESS_OCR_ROTATE_PAGES=` + +: Tells paperless to correct page rotation (90°, 180° and 270° +rotation). + + If you notice that paperless is not rotating incorrectly rotated + pages (or vice versa), try adjusting the threshold up or down (see + below). + + Defaults to `true`, which enables this feature. + +`PAPERLESS_OCR_ROTATE_PAGES_THRESHOLD=` + +: Adjust the threshold for automatic page rotation by +`PAPERLESS_OCR_ROTATE_PAGES`. This is an arbitrary value reported by +tesseract. "15" is a very conservative value, whereas "2" is a +very aggressive option and will often result in correctly rotated +pages being rotated as well. + + Defaults to "12". + +`PAPERLESS_OCR_OUTPUT_TYPE=` + +: Specify the the type of PDF documents that paperless should produce. + + - `pdf`: Modify the PDF document as little as possible. + - `pdfa`: Convert PDF documents into PDF/A-2b documents, which is + a subset of the entire PDF specification and meant for storing + documents long term. + - `pdfa-1`, `pdfa-2`, `pdfa-3` to specify the exact version of + PDF/A you wish to use. + + If not specified, `pdfa` is used. Remember that paperless also keeps + the original input file as well as the archived version. + +`PAPERLESS_OCR_PAGES=` + +: Tells paperless to use only the specified amount of pages for OCR. +Documents with less than the specified amount of pages get OCR'ed +completely. + + Specifying 1 here will only use the first page. + + When combined with `PAPERLESS_OCR_MODE=redo` or + `PAPERLESS_OCR_MODE=force`, paperless will not modify any text it + finds on excluded pages and copy it verbatim. + + Defaults to 0, which disables this feature and always uses all + pages. + +`PAPERLESS_OCR_IMAGE_DPI=` + +: Paperless will OCR any images you put into the system and convert +them into PDF documents. This is useful if your scanner produces +images. In order to do so, paperless needs to know the DPI of the +image. Most images from scanners will have this information embedded +and paperless will detect and use that information. In case this +fails, it uses this value as a fallback. + + Set this to the DPI your scanner produces images at. + + Default is none, which will automatically calculate image DPI so + that the produced PDF documents are A4 sized. + +`PAPERLESS_OCR_MAX_IMAGE_PIXELS=` + +: Paperless will raise a warning when OCRing images which are over +this limit and will not OCR images which are more than twice this +limit. Note this does not prevent the document from being consumed, +but could result in missing text content. + + If unset, will default to the value determined by + [Pillow](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.MAX_IMAGE_PIXELS). + + !!! note + + Increasing this limit could cause Paperless to consume additional + resources when consuming a file. Be sure you have sufficient system + resources. + + !!! warning + + The limit is intended to prevent malicious files from consuming + system resources and causing crashes and other errors. Only increase + this value if you are certain your documents are not malicious and + you need the text which was not OCRed + +`PAPERLESS_OCR_USER_ARGS=` + +: OCRmyPDF offers many more options. Use this parameter to specify any +additional arguments you wish to pass to OCRmyPDF. Since Paperless +uses the API of OCRmyPDF, you have to specify these in a format that +can be passed to the API. See [the API reference of +OCRmyPDF](https://ocrmypdf.readthedocs.io/en/latest/api.html#reference) +for valid parameters. All command line options are supported, but +they use underscores instead of dashes. + + !!! warning + + Paperless has been tested to work with the OCR options provided + above. There are many options that are incompatible with each other, + so specifying invalid options may prevent paperless from consuming + any documents. + + Specify arguments as a JSON dictionary. Keep note of lower case + booleans and double quoted parameter names and strings. Examples: + + ``` json + {"deskew": true, "optimize": 3, "unpaper_args": "--pre-rotate 90"} + ``` + +## Tika settings {#tika} + +Paperless can make use of [Tika](https://tika.apache.org/) and +[Gotenberg](https://gotenberg.dev/) for parsing and converting +"Office" documents (such as ".doc", ".xlsx" and ".odt"). +Tika and Gotenberg are also needed to allow parsing of E-Mails (.eml). + +If you wish to use this, you must provide a Tika server and a Gotenberg server, +configure their endpoints, and enable the feature. + +`PAPERLESS_TIKA_ENABLED=` + +: Enable (or disable) the Tika parser. + + Defaults to false. + +`PAPERLESS_TIKA_ENDPOINT=` + +: Set the endpoint URL were Paperless can reach your Tika server. + + Defaults to "". + +`PAPERLESS_TIKA_GOTENBERG_ENDPOINT=` + +: Set the endpoint URL were Paperless can reach your Gotenberg server. + + Defaults to "". + +If you run paperless on docker, you can add those services to the +docker-compose file (see the provided `docker-compose.sqlite-tika.yml` +file for reference). The changes requires are as follows: + +```yaml +services: + # ... + + webserver: + # ... + + environment: + # ... + + PAPERLESS_TIKA_ENABLED: 1 + PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000 + PAPERLESS_TIKA_ENDPOINT: http://tika:9998 + + # ... + + gotenberg: + image: gotenberg/gotenberg:7.6 + restart: unless-stopped + # The gotenberg chromium route is used to convert .eml files. We do not + # want to allow external content like tracking pixels or even javascript. + command: + - 'gotenberg' + - '--chromium-disable-javascript=true' + - '--chromium-allow-list=file:///tmp/.*' + + tika: + image: ghcr.io/paperless-ngx/tika:latest + restart: unless-stopped +``` + +Add the configuration variables to the environment of the webserver +(alternatively put the configuration in the `docker-compose.env` file) +and add the additional services below the webserver service. Watch out +for indentation. + +Make sure to use the correct format [PAPERLESS_TIKA_ENABLED = +1]{.title-ref} so python_dotenv can parse the statement correctly. + +## Software tweaks {#software_tweaks} + +`PAPERLESS_TASK_WORKERS=` + +: Paperless does multiple things in the background: Maintain the +search index, maintain the automatic matching algorithm, check +emails, consume documents, etc. This variable specifies how many +things it will do in parallel. + + Defaults to 1 + +`PAPERLESS_THREADS_PER_WORKER=` + +: Furthermore, paperless uses multiple threads when consuming +documents to speed up OCR. This variable specifies how many pages +paperless will process in parallel on a single document. + + !!! warning + + Ensure that the product + + `PAPERLESS_TASK_WORKERS \: PAPERLESS_THREADS_PER_WORKER` + + does not exceed your CPU core count or else paperless will be + extremely slow. If you want paperless to process many documents in + parallel, choose a high worker count. If you want paperless to + process very large documents faster, use a higher thread per worker + count. + + The default is a balance between the two, according to your CPU core + count, with a slight favor towards threads per worker: + + | CPU core count | Workers | Threads | + |----------------|---------|---------| + | > 1 | > 1 | > 1 | + | > 2 | > 2 | > 1 | + | > 4 | > 2 | > 2 | + | > 6 | > 2 | > 3 | + | > 8 | > 2 | > 4 | + | > 12 | > 3 | > 4 | + | > 16 | > 4 | > 4 | + + If you only specify PAPERLESS_TASK_WORKERS, paperless will adjust + PAPERLESS_THREADS_PER_WORKER automatically. + +`PAPERLESS_WORKER_TIMEOUT=` + +: Machines with few cores or weak ones might not be able to finish OCR +on large documents within the default 1800 seconds. So extending +this timeout may prove to be useful on weak hardware setups. + +`PAPERLESS_WORKER_RETRY=` + +: If PAPERLESS_WORKER_TIMEOUT has been configured, the retry time for +a task can also be configured. By default, this value will be set to +10s more than the worker timeout. This value should never be set +less than the worker timeout. + +`PAPERLESS_TIME_ZONE=` + +: Set the time zone here. See + +for details on how to set it. + + Defaults to UTC. + +## Polling {#polling} + +`PAPERLESS_CONSUMER_POLLING=` + +: If paperless won't find documents added to your consume folder, it +might not be able to automatically detect filesystem changes. In +that case, specify a polling interval in seconds here, which will +then cause paperless to periodically check your consumption +directory for changes. This will also disable listening for file +system changes with `inotify`. + + Defaults to 0, which disables polling and uses filesystem + notifications. + +`PAPERLESS_CONSUMER_POLLING_RETRY_COUNT=` + +: If consumer polling is enabled, sets the number of times paperless +will check for a file to remain unmodified. + + Defaults to 5. + +`PAPERLESS_CONSUMER_POLLING_DELAY=` + +: If consumer polling is enabled, sets the delay in seconds between +each check (above) paperless will do while waiting for a file to +remain unmodified. + + Defaults to 5. + +## iNotify {#inotify} + +`PAPERLESS_CONSUMER_INOTIFY_DELAY=` + +: Sets the time in seconds the consumer will wait for additional +events from inotify before the consumer will consider a file ready +and begin consumption. Certain scanners or network setups may +generate multiple events for a single file, leading to multiple +consumers working on the same file. Configure this to prevent that. + + Defaults to 0.5 seconds. + +`PAPERLESS_CONSUMER_DELETE_DUPLICATES=` + +: When the consumer detects a duplicate document, it will not touch +the original document. This default behavior can be changed here. + + Defaults to false. + +`PAPERLESS_CONSUMER_RECURSIVE=` + +: Enable recursive watching of the consumption directory. Paperless +will then pickup files from files in subdirectories within your +consumption directory as well. + + Defaults to false. + +`PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS=` + +: Set the names of subdirectories as tags for consumed files. E.g. +/foo/bar/file.pdf will add the tags "foo" and +"bar" to the consumed file. Paperless will create any tags that +don't exist yet. + + This is useful for sorting documents with certain tags such as `car` + or `todo` prior to consumption. These folders won't be deleted. + + PAPERLESS_CONSUMER_RECURSIVE must be enabled for this to work. + + Defaults to false. + +`PAPERLESS_CONSUMER_ENABLE_BARCODES=` + +: Enables the scanning and page separation based on detected barcodes. +This allows for scanning and adding multiple documents per uploaded +file, which are separated by one or multiple barcode pages. + + For ease of use, it is suggested to use a standardized separation + page, e.g. [here](https://www.alliancegroup.co.uk/patch-codes.htm). + + If no barcodes are detected in the uploaded file, no page separation + will happen. + + The original document will be removed and the separated pages will + be saved as pdf. + + Defaults to false. + +`PAPERLESS_CONSUMER_BARCODE_TIFF_SUPPORT=` + +: Whether TIFF image files should be scanned for barcodes. This will +automatically convert any TIFF image(s) to pdfs for later +processing. This only has an effect, if +PAPERLESS_CONSUMER_ENABLE_BARCODES has been enabled. + + Defaults to false. + +PAPERLESS_CONSUMER_BARCODE_STRING=PATCHT + +: Defines the string to be detected as a separator barcode. If +paperless is used with the PATCH-T separator pages, users shouldn't +change this. + + Defaults to "PATCHT" + +`PAPERLESS_CONVERT_MEMORY_LIMIT=` + +: On smaller systems, or even in the case of Very Large Documents, the +consumer may explode, complaining about how it's "unable to extend +pixel cache". In such cases, try setting this to a reasonably low +value, like 32. The default is to use whatever is necessary to do +everything without writing to disk, and units are in megabytes. + + For more information on how to use this value, you should search the + web for "MAGICK_MEMORY_LIMIT". + + Defaults to 0, which disables the limit. + +`PAPERLESS_CONVERT_TMPDIR=` + +: Similar to the memory limit, if you've got a small system and your +OS mounts /tmp as tmpfs, you should set this to a path that's on a +physical disk, like /home/your_user/tmp or something. ImageMagick +will use this as scratch space when crunching through very large +documents. + + For more information on how to use this value, you should search the + web for "MAGICK_TMPDIR". + + Default is none, which disables the temporary directory. + +`PAPERLESS_POST_CONSUME_SCRIPT=` + +: After a document is consumed, Paperless can trigger an arbitrary +script if you like. This script will be passed a number of arguments +for you to work with. For more information, take a look at [Post-consumption script](advanced_usage#post_consume_script). + + The default is blank, which means nothing will be executed. + +`PAPERLESS_FILENAME_DATE_ORDER=` + +: Paperless will check the document text for document date +information. Use this setting to enable checking the document +filename for date information. The date order can be set to any +option as specified in +. +The filename will be checked first, and if nothing is found, the +document text will be checked as normal. + + A date in a filename must have some separators ([.]{.title-ref}, + [-]{.title-ref}, [/]{.title-ref}, etc) for it to be parsed. + + Defaults to none, which disables this feature. + +`PAPERLESS_NUMBER_OF_SUGGESTED_DATES=` + +: Paperless searches an entire document for dates. The first date +found will be used as the initial value for the created date. When +this variable is greater than 0 (or left to it's default value), +paperless will also suggest other dates found in the document, up to +a maximum of this setting. Note that duplicates will be removed, +which can result in fewer dates displayed in the frontend than this +setting value. + + The task to find all dates can be time-consuming and increases with + a higher (maximum) number of suggested dates and slower hardware. + + Defaults to 3. Set to 0 to disable this feature. + +`PAPERLESS_THUMBNAIL_FONT_NAME=` + +: Paperless creates thumbnails for plain text files by rendering the +content of the file on an image and uses a predefined font for that. +This font can be changed here. + + Note that this won't have any effect on already generated + thumbnails. + + Defaults to + `/usr/share/fonts/liberation/LiberationSerif-Regular.ttf`. + +`PAPERLESS_IGNORE_DATES=` + +: Paperless parses a documents creation date from filename and file +content. You may specify a comma separated list of dates that should +be ignored during this process. This is useful for special dates +(like date of birth) that appear in documents regularly but are very +unlikely to be the documents creation date. + + The date is parsed using the order specified in PAPERLESS_DATE_ORDER + + Defaults to an empty string to not ignore any dates. + +`PAPERLESS_DATE_ORDER=` + +: Paperless will try to determine the document creation date from its +contents. Specify the date format Paperless should expect to see +within your documents. + + This option defaults to DMY which translates to day first, month + second, and year last order. Characters D, M, or Y can be shuffled + to meet the required order. + +`PAPERLESS_CONSUMER_IGNORE_PATTERNS=` + +: By default, paperless ignores certain files and folders in the +consumption directory, such as system files created by the Mac OS. + + This can be adjusted by configuring a custom json array with + patterns to exclude. + + Defaults to + `[".DS_STORE/*", "._*", ".stfolder/*", ".stversions/*", ".localized/*", "desktop.ini"]`. + +## Binaries + +There are a few external software packages that Paperless expects to +find on your system when it starts up. Unless you've done something +creative with their installation, you probably won't need to edit any +of these. However, if you've installed these programs somewhere where +simply typing the name of the program doesn't automatically execute it +(ie. the program isn't in your \$PATH), then you'll need to specify +the literal path for that program. + +`PAPERLESS_CONVERT_BINARY=` + +: Defaults to "convert". + +`PAPERLESS_GS_BINARY=` + +: Defaults to "gs". + +## Docker-specific options {#docker} + +These options don't have any effect in `paperless.conf`. These options +adjust the behavior of the docker container. Configure these in +[docker-compose.env]{.title-ref}. + +`PAPERLESS_WEBSERVER_WORKERS=` + +: The number of worker processes the webserver should spawn. More +worker processes usually result in the front end to load data much +quicker. However, each worker process also loads the entire +application into memory separately, so increasing this value will +increase RAM usage. + + Defaults to 1. + +`PAPERLESS_BIND_ADDR=` + +: The IP address the webserver will listen on inside the container. +There are special setups where you may need to configure this value +to restrict the Ip address or interface the webserver listens on. + + Defaults to \[::\], meaning all interfaces, including IPv6. + +`PAPERLESS_PORT=` + +: The port number the webserver will listen on inside the container. +There are special setups where you may need this to avoid collisions +with other services (like using podman with multiple containers in +one pod). + + Don't change this when using Docker. To change the port the + webserver is reachable outside of the container, instead refer to + the "ports" key in `docker-compose.yml`. + + Defaults to 8000. + +`USERMAP_UID=` + +: The ID of the paperless user in the container. Set this to your +actual user ID on the host system, which you can get by executing + + ``` shell-session + $ id -u + ``` + + Paperless will change ownership on its folders to this user, so you + need to get this right in order to be able to write to the + consumption directory. + + Defaults to 1000. + +`USERMAP_GID=` + +: The ID of the paperless Group in the container. Set this to your +actual group ID on the host system, which you can get by executing + + ``` shell-session + $ id -g + ``` + + Paperless will change ownership on its folders to this group, so you + need to get this right in order to be able to write to the + consumption directory. + + Defaults to 1000. + +`PAPERLESS_OCR_LANGUAGES=` + +: Additional OCR languages to install. By default, paperless comes +with English, German, Italian, Spanish and French. If your language +is not in this list, install additional languages with this +configuration option: + + ``` bash + PAPERLESS_OCR_LANGUAGES=tur ces + ``` + + To actually use these languages, also set the default OCR language + of paperless: + + ``` bash + PAPERLESS_OCR_LANGUAGE=tur + ``` + + Defaults to none, which does not install any additional languages. + +`PAPERLESS_ENABLE_FLOWER=` + +: If this environment variable is defined, the Celery monitoring tool +[Flower](https://flower.readthedocs.io/en/latest/index.html) will be +started by the container. + + You can read more about this in the [advanced documentation](advanced#celery-monitoring). + +## Update Checking {#update-checking} + +`PAPERLESS_ENABLE_UPDATE_CHECK=` + +!!! note + + This setting was deprecated in favor of a frontend setting after + v1.9.2. A one-time migration is performed for users who have this + setting set. This setting is always ignored if the corresponding + frontend setting has been set. diff --git a/docs/configuration.rst b/docs/configuration.rst deleted file mode 100644 index f9c4f89cc..000000000 --- a/docs/configuration.rst +++ /dev/null @@ -1,925 +0,0 @@ -.. _configuration: - -************* -Configuration -************* - -Paperless provides a wide range of customizations. -Depending on how you run paperless, these settings have to be defined in different -places. - -* If you run paperless on docker, ``paperless.conf`` is not used. Rather, configure - paperless by copying necessary options to ``docker-compose.env``. -* If you are running paperless on anything else, paperless will search for the - configuration file in these locations and use the first one it finds: - - .. code:: - - /path/to/paperless/paperless.conf - /etc/paperless.conf - /usr/local/etc/paperless.conf - - -Required services -################# - -PAPERLESS_REDIS= - This is required for processing scheduled tasks such as email fetching, index - optimization and for training the automatic document matcher. - - * If your Redis server needs login credentials PAPERLESS_REDIS = ``redis://:@:`` - - * With the requirepass option PAPERLESS_REDIS = ``redis://:@:`` - - `More information on securing your Redis Instance `_. - - Defaults to redis://localhost:6379. - -PAPERLESS_DBENGINE= - Optional, gives the ability to choose Postgres or MariaDB for database engine. - Available options are `postgresql` and `mariadb`. - Default is `postgresql`. - -PAPERLESS_DBHOST= - By default, sqlite is used as the database backend. This can be changed here. - - Set PAPERLESS_DBHOST and another database will be used instead of sqlite. - -PAPERLESS_DBPORT= - Adjust port if necessary. - - Default is 5432. - -PAPERLESS_DBNAME= - Database name in PostgreSQL or MariaDB. - - Defaults to "paperless". - -PAPERLESS_DBUSER= - Database user in PostgreSQL or MariaDB. - - Defaults to "paperless". - -PAPERLESS_DBPASS= - Database password for PostgreSQL or MariaDB. - - Defaults to "paperless". - -PAPERLESS_DBSSLMODE= - SSL mode to use when connecting to PostgreSQL. - - See `the official documentation about sslmode `_. - - Default is ``prefer``. - -PAPERLESS_DB_TIMEOUT= - Amount of time for a database connection to wait for the database to unlock. - Mostly applicable for an sqlite based installation, consider changing to postgresql - if you need to increase this. - - Defaults to unset, keeping the Django defaults. - -Paths and folders -################# - -PAPERLESS_CONSUMPTION_DIR= - This where your documents should go to be consumed. Make sure that it exists - and that the user running the paperless service can read/write its contents - before you start Paperless. - - Don't change this when using docker, as it only changes the path within the - container. Change the local consumption directory in the docker-compose.yml - file instead. - - Defaults to "../consume/", relative to the "src" directory. - -PAPERLESS_DATA_DIR= - This is where paperless stores all its data (search index, SQLite database, - classification model, etc). - - Defaults to "../data/", relative to the "src" directory. - -PAPERLESS_TRASH_DIR= - Instead of removing deleted documents, they are moved to this directory. - - This must be writeable by the user running paperless. When running inside - docker, ensure that this path is within a permanent volume (such as - "../media/trash") so it won't get lost on upgrades. - - Defaults to empty (i.e. really delete documents). - -PAPERLESS_MEDIA_ROOT= - This is where your documents and thumbnails are stored. - - You can set this and PAPERLESS_DATA_DIR to the same folder to have paperless - store all its data within the same volume. - - Defaults to "../media/", relative to the "src" directory. - -PAPERLESS_STATICDIR= - Override the default STATIC_ROOT here. This is where all static files - created using "collectstatic" manager command are stored. - - Unless you're doing something fancy, there is no need to override this. - - Defaults to "../static/", relative to the "src" directory. - -PAPERLESS_FILENAME_FORMAT= - Changes the filenames paperless uses to store documents in the media directory. - See :ref:`advanced-file_name_handling` for details. - - Default is none, which disables this feature. - -PAPERLESS_FILENAME_FORMAT_REMOVE_NONE= - Tells paperless to replace placeholders in `PAPERLESS_FILENAME_FORMAT` that would resolve - to 'none' to be omitted from the resulting filename. This also holds true for directory - names. - See :ref:`advanced-file_name_handling` for details. - - Defaults to `false` which disables this feature. - -PAPERLESS_LOGGING_DIR= - This is where paperless will store log files. - - Defaults to "``PAPERLESS_DATA_DIR``/log/". - - -Logging -####### - -PAPERLESS_LOGROTATE_MAX_SIZE= - Maximum file size for log files before they are rotated, in bytes. - - Defaults to 1 MiB. - -PAPERLESS_LOGROTATE_MAX_BACKUPS= - Number of rotated log files to keep. - - Defaults to 20. - -.. _hosting-and-security: - -Hosting & Security -################## - -PAPERLESS_SECRET_KEY= - Paperless uses this to make session tokens. If you expose paperless on the - internet, you need to change this, since the default secret is well known. - - Use any sequence of characters. The more, the better. You don't need to - remember this. Just face-roll your keyboard. - - Default is listed in the file ``src/paperless/settings.py``. - -PAPERLESS_URL= - This setting can be used to set the three options below (ALLOWED_HOSTS, - CORS_ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS). If the other options are - set the values will be combined with this one. Do not include a trailing - slash. E.g. https://paperless.domain.com - - Defaults to empty string, leaving the other settings unaffected. - -PAPERLESS_CSRF_TRUSTED_ORIGINS= - A list of trusted origins for unsafe requests (e.g. POST). As of Django 4.0 - this is required to access the Django admin via the web. - See https://docs.djangoproject.com/en/4.0/ref/settings/#csrf-trusted-origins - - Can also be set using PAPERLESS_URL (see above). - - Defaults to empty string, which does not add any origins to the trusted list. - -PAPERLESS_ALLOWED_HOSTS= - If you're planning on putting Paperless on the open internet, then you - really should set this value to the domain name you're using. Failing to do - so leaves you open to HTTP host header attacks: - https://docs.djangoproject.com/en/3.1/topics/security/#host-header-validation - - Just remember that this is a comma-separated list, so "example.com" is fine, - as is "example.com,www.example.com", but NOT " example.com" or "example.com," - - Can also be set using PAPERLESS_URL (see above). - - If manually set, please remember to include "localhost". Otherwise docker - healthcheck will fail. - - Defaults to "*", which is all hosts. - -PAPERLESS_CORS_ALLOWED_HOSTS= - You need to add your servers to the list of allowed hosts that can do CORS - calls. Set this to your public domain name. - - Can also be set using PAPERLESS_URL (see above). - - Defaults to "http://localhost:8000". - -PAPERLESS_FORCE_SCRIPT_NAME= - To host paperless under a subpath url like example.com/paperless you set - this value to /paperless. No trailing slash! - - Defaults to none, which hosts paperless at "/". - -PAPERLESS_STATIC_URL= - Override the STATIC_URL here. Unless you're hosting Paperless off a - subdomain like /paperless/, you probably don't need to change this. - If you do change it, be sure to include the trailing slash. - - Defaults to "/static/". - - .. note:: - - When hosting paperless behind a reverse proxy like Traefik or Nginx at a subpath e.g. - example.com/paperlessngx you will also need to set ``PAPERLESS_FORCE_SCRIPT_NAME`` - (see above). - -PAPERLESS_AUTO_LOGIN_USERNAME= - Specify a username here so that paperless will automatically perform login - with the selected user. - - .. danger:: - - Do not use this when exposing paperless on the internet. There are no - checks in place that would prevent you from doing this. - - Defaults to none, which disables this feature. - -PAPERLESS_ADMIN_USER= - If this environment variable is specified, Paperless automatically creates - a superuser with the provided username at start. This is useful in cases - where you can not run the `createsuperuser` command separately, such as Kubernetes - or AWS ECS. - - Requires `PAPERLESS_ADMIN_PASSWORD` to be set. - - .. note:: - - This will not change an existing [super]user's password, nor will - it recreate a user that already exists. You can leave this throughout - the lifecycle of the containers. - -PAPERLESS_ADMIN_MAIL= - (Optional) Specify superuser email address. Only used when - `PAPERLESS_ADMIN_USER` is set. - - Defaults to ``root@localhost``. - -PAPERLESS_ADMIN_PASSWORD= - Only used when `PAPERLESS_ADMIN_USER` is set. - This will be the password of the automatically created superuser. - - -PAPERLESS_COOKIE_PREFIX= - Specify a prefix that is added to the cookies used by paperless to identify - the currently logged in user. This is useful for when you're running two - instances of paperless on the same host. - - After changing this, you will have to login again. - - Defaults to ``""``, which does not alter the cookie names. - -PAPERLESS_ENABLE_HTTP_REMOTE_USER= - Allows authentication via HTTP_REMOTE_USER which is used by some SSO - applications. - - .. warning:: - - This will allow authentication by simply adding a ``Remote-User: `` header - to a request. Use with care! You especially *must* ensure that any such header is not - passed from your proxy server to paperless. - - If you're exposing paperless to the internet directly, do not use this. - - Also see the warning `in the official documentation `. - - Defaults to `false` which disables this feature. - -PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME= - If `PAPERLESS_ENABLE_HTTP_REMOTE_USER` is enabled, this property allows to - customize the name of the HTTP header from which the authenticated username - is extracted. Values are in terms of - [HttpRequest.META](https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.HttpRequest.META). - Thus, the configured value must start with `HTTP_` followed by the - normalized actual header name. - - Defaults to `HTTP_REMOTE_USER`. - -PAPERLESS_LOGOUT_REDIRECT_URL= - URL to redirect the user to after a logout. This can be used together with - `PAPERLESS_ENABLE_HTTP_REMOTE_USER` to redirect the user back to the SSO - application's logout page. - - Defaults to None, which disables this feature. - -.. _configuration-ocr: - -OCR settings -############ - -Paperless uses `OCRmyPDF `_ for -performing OCR on documents and images. Paperless uses sensible defaults for -most settings, but all of them can be configured to your needs. - -PAPERLESS_OCR_LANGUAGE= - Customize the language that paperless will attempt to use when - parsing documents. - - It should be a 3-letter language code consistent with ISO - 639: https://www.loc.gov/standards/iso639-2/php/code_list.php - - Set this to the language most of your documents are written in. - - This can be a combination of multiple languages such as ``deu+eng``, - in which case tesseract will use whatever language matches best. - Keep in mind that tesseract uses much more cpu time with multiple - languages enabled. - - Defaults to "eng". - - Note: If your language contains a '-' such as chi-sim, you must use chi_sim - -PAPERLESS_OCR_MODE= - Tell paperless when and how to perform ocr on your documents. Four modes - are available: - - * ``skip``: Paperless skips all pages and will perform ocr only on pages - where no text is present. This is the safest option. - * ``skip_noarchive``: In addition to skip, paperless won't create an - archived version of your documents when it finds any text in them. - This is useful if you don't want to have two almost-identical versions - of your digital documents in the media folder. This is the fastest option. - * ``redo``: Paperless will OCR all pages of your documents and attempt to - replace any existing text layers with new text. This will be useful for - documents from scanners that already performed OCR with insufficient - results. It will also perform OCR on purely digital documents. - - This option may fail on some documents that have features that cannot - be removed, such as forms. In this case, the text from the document is - used instead. - * ``force``: Paperless rasterizes your documents, converting any text - into images and puts the OCRed text on top. This works for all documents, - however, the resulting document may be significantly larger and text - won't appear as sharp when zoomed in. - - The default is ``skip``, which only performs OCR when necessary and always - creates archived documents. - - Read more about this in the `OCRmyPDF documentation `_. - -PAPERLESS_OCR_CLEAN= - Tells paperless to use ``unpaper`` to clean any input document before - sending it to tesseract. This uses more resources, but generally results - in better OCR results. The following modes are available: - - * ``clean``: Apply unpaper. - * ``clean-final``: Apply unpaper, and use the cleaned images to build the - output file instead of the original images. - * ``none``: Do not apply unpaper. - - Defaults to ``clean``. - - .. note:: - - ``clean-final`` is incompatible with ocr mode ``redo``. When both - ``clean-final`` and the ocr mode ``redo`` is configured, ``clean`` - is used instead. - -PAPERLESS_OCR_DESKEW= - Tells paperless to correct skewing (slight rotation of input images mainly - due to improper scanning) - - Defaults to ``true``, which enables this feature. - - .. note:: - - Deskewing is incompatible with ocr mode ``redo``. Deskewing will get - disabled automatically if ``redo`` is used as the ocr mode. - -PAPERLESS_OCR_ROTATE_PAGES= - Tells paperless to correct page rotation (90°, 180° and 270° rotation). - - If you notice that paperless is not rotating incorrectly rotated - pages (or vice versa), try adjusting the threshold up or down (see below). - - Defaults to ``true``, which enables this feature. - - -PAPERLESS_OCR_ROTATE_PAGES_THRESHOLD= - Adjust the threshold for automatic page rotation by ``PAPERLESS_OCR_ROTATE_PAGES``. - This is an arbitrary value reported by tesseract. "15" is a very conservative value, - whereas "2" is a very aggressive option and will often result in correctly rotated pages - being rotated as well. - - Defaults to "12". - -PAPERLESS_OCR_OUTPUT_TYPE= - Specify the the type of PDF documents that paperless should produce. - - * ``pdf``: Modify the PDF document as little as possible. - * ``pdfa``: Convert PDF documents into PDF/A-2b documents, which is a - subset of the entire PDF specification and meant for storing - documents long term. - * ``pdfa-1``, ``pdfa-2``, ``pdfa-3`` to specify the exact version of - PDF/A you wish to use. - - If not specified, ``pdfa`` is used. Remember that paperless also keeps - the original input file as well as the archived version. - - -PAPERLESS_OCR_PAGES= - Tells paperless to use only the specified amount of pages for OCR. Documents - with less than the specified amount of pages get OCR'ed completely. - - Specifying 1 here will only use the first page. - - When combined with ``PAPERLESS_OCR_MODE=redo`` or ``PAPERLESS_OCR_MODE=force``, - paperless will not modify any text it finds on excluded pages and copy it - verbatim. - - Defaults to 0, which disables this feature and always uses all pages. - -PAPERLESS_OCR_IMAGE_DPI= - Paperless will OCR any images you put into the system and convert them - into PDF documents. This is useful if your scanner produces images. - In order to do so, paperless needs to know the DPI of the image. - Most images from scanners will have this information embedded and - paperless will detect and use that information. In case this fails, it - uses this value as a fallback. - - Set this to the DPI your scanner produces images at. - - Default is none, which will automatically calculate image DPI so that - the produced PDF documents are A4 sized. - -PAPERLESS_OCR_MAX_IMAGE_PIXELS= - Paperless will raise a warning when OCRing images which are over this limit and - will not OCR images which are more than twice this limit. Note this does not - prevent the document from being consumed, but could result in missing text content. - - If unset, will default to the value determined by - `Pillow `_. - - .. note:: - - Increasing this limit could cause Paperless to consume additional resources - when consuming a file. Be sure you have sufficient system resources. - - .. caution:: - - The limit is intended to prevent malicious files from consuming system resources - and causing crashes and other errors. Only increase this value if you are certain - your documents are not malicious and you need the text which was not OCRed - -PAPERLESS_OCR_USER_ARGS= - OCRmyPDF offers many more options. Use this parameter to specify any - additional arguments you wish to pass to OCRmyPDF. Since Paperless uses - the API of OCRmyPDF, you have to specify these in a format that can be - passed to the API. See `the API reference of OCRmyPDF `_ - for valid parameters. All command line options are supported, but they - use underscores instead of dashes. - - .. caution:: - - Paperless has been tested to work with the OCR options provided - above. There are many options that are incompatible with each other, - so specifying invalid options may prevent paperless from consuming - any documents. - - Specify arguments as a JSON dictionary. Keep note of lower case booleans - and double quoted parameter names and strings. Examples: - - .. code:: json - - {"deskew": true, "optimize": 3, "unpaper_args": "--pre-rotate 90"} - -.. _configuration-tika: - -Tika settings -############# - -Paperless can make use of `Tika `_ and -`Gotenberg `_ for parsing and -converting "Office" documents (such as ".doc", ".xlsx" and ".odt"). If you -wish to use this, you must provide a Tika server and a Gotenberg server, -configure their endpoints, and enable the feature. - -PAPERLESS_TIKA_ENABLED= - Enable (or disable) the Tika parser. - - Defaults to false. - -PAPERLESS_TIKA_ENDPOINT= - Set the endpoint URL were Paperless can reach your Tika server. - - Defaults to "http://localhost:9998". - -PAPERLESS_TIKA_GOTENBERG_ENDPOINT= - Set the endpoint URL were Paperless can reach your Gotenberg server. - - Defaults to "http://localhost:3000". - -If you run paperless on docker, you can add those services to the docker-compose -file (see the provided ``docker-compose.sqlite-tika.yml`` file for reference). The changes -requires are as follows: - -.. code:: yaml - - services: - # ... - - webserver: - # ... - - environment: - # ... - - PAPERLESS_TIKA_ENABLED: 1 - PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000 - PAPERLESS_TIKA_ENDPOINT: http://tika:9998 - - # ... - - gotenberg: - image: gotenberg/gotenberg:7.6 - restart: unless-stopped - command: - - "gotenberg" - - "--chromium-disable-routes=true" - - tika: - image: ghcr.io/paperless-ngx/tika:latest - restart: unless-stopped - -Add the configuration variables to the environment of the webserver (alternatively -put the configuration in the ``docker-compose.env`` file) and add the additional -services below the webserver service. Watch out for indentation. - -Make sure to use the correct format `PAPERLESS_TIKA_ENABLED = 1` so python_dotenv can parse the statement correctly. - -Software tweaks -############### - -PAPERLESS_TASK_WORKERS= - Paperless does multiple things in the background: Maintain the search index, - maintain the automatic matching algorithm, check emails, consume documents, - etc. This variable specifies how many things it will do in parallel. - - Defaults to 1 - - -PAPERLESS_THREADS_PER_WORKER= - Furthermore, paperless uses multiple threads when consuming documents to - speed up OCR. This variable specifies how many pages paperless will process - in parallel on a single document. - - .. caution:: - - Ensure that the product - - PAPERLESS_TASK_WORKERS * PAPERLESS_THREADS_PER_WORKER - - does not exceed your CPU core count or else paperless will be extremely slow. - If you want paperless to process many documents in parallel, choose a high - worker count. If you want paperless to process very large documents faster, - use a higher thread per worker count. - - The default is a balance between the two, according to your CPU core count, - with a slight favor towards threads per worker: - - +----------------+---------+---------+ - | CPU core count | Workers | Threads | - +----------------+---------+---------+ - | 1 | 1 | 1 | - +----------------+---------+---------+ - | 2 | 2 | 1 | - +----------------+---------+---------+ - | 4 | 2 | 2 | - +----------------+---------+---------+ - | 6 | 2 | 3 | - +----------------+---------+---------+ - | 8 | 2 | 4 | - +----------------+---------+---------+ - | 12 | 3 | 4 | - +----------------+---------+---------+ - | 16 | 4 | 4 | - +----------------+---------+---------+ - - If you only specify PAPERLESS_TASK_WORKERS, paperless will adjust - PAPERLESS_THREADS_PER_WORKER automatically. - - -PAPERLESS_WORKER_TIMEOUT= - Machines with few cores or weak ones might not be able to finish OCR on - large documents within the default 1800 seconds. So extending this timeout - may prove to be useful on weak hardware setups. - -PAPERLESS_WORKER_RETRY= - If PAPERLESS_WORKER_TIMEOUT has been configured, the retry time for a task can - also be configured. By default, this value will be set to 10s more than the - worker timeout. This value should never be set less than the worker timeout. - -PAPERLESS_TIME_ZONE= - Set the time zone here. - See https://docs.djangoproject.com/en/3.1/ref/settings/#std:setting-TIME_ZONE - for details on how to set it. - - Defaults to UTC. - - -.. _configuration-polling: - -PAPERLESS_CONSUMER_POLLING= - If paperless won't find documents added to your consume folder, it might - not be able to automatically detect filesystem changes. In that case, - specify a polling interval in seconds here, which will then cause paperless - to periodically check your consumption directory for changes. This will also - disable listening for file system changes with ``inotify``. - - Defaults to 0, which disables polling and uses filesystem notifications. - -PAPERLESS_CONSUMER_POLLING_RETRY_COUNT= - If consumer polling is enabled, sets the number of times paperless will check for a - file to remain unmodified. - - Defaults to 5. - -PAPERLESS_CONSUMER_POLLING_DELAY= - If consumer polling is enabled, sets the delay in seconds between each check (above) paperless - will do while waiting for a file to remain unmodified. - - Defaults to 5. - -.. _configuration-inotify: - -PAPERLESS_CONSUMER_INOTIFY_DELAY= - Sets the time in seconds the consumer will wait for additional events - from inotify before the consumer will consider a file ready and begin consumption. - Certain scanners or network setups may generate multiple events for a single file, - leading to multiple consumers working on the same file. Configure this to - prevent that. - - Defaults to 0.5 seconds. - -PAPERLESS_CONSUMER_DELETE_DUPLICATES= - When the consumer detects a duplicate document, it will not touch the - original document. This default behavior can be changed here. - - Defaults to false. - - -PAPERLESS_CONSUMER_RECURSIVE= - Enable recursive watching of the consumption directory. Paperless will - then pickup files from files in subdirectories within your consumption - directory as well. - - Defaults to false. - - -PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS= - Set the names of subdirectories as tags for consumed files. - E.g. /foo/bar/file.pdf will add the tags "foo" and "bar" to - the consumed file. Paperless will create any tags that don't exist yet. - - This is useful for sorting documents with certain tags such as ``car`` or - ``todo`` prior to consumption. These folders won't be deleted. - - PAPERLESS_CONSUMER_RECURSIVE must be enabled for this to work. - - Defaults to false. - -PAPERLESS_CONSUMER_ENABLE_BARCODES= - Enables the scanning and page separation based on detected barcodes. - This allows for scanning and adding multiple documents per uploaded - file, which are separated by one or multiple barcode pages. - - For ease of use, it is suggested to use a standardized separation page, - e.g. `here `_. - - If no barcodes are detected in the uploaded file, no page separation - will happen. - - The original document will be removed and the separated pages will be - saved as pdf. - - Defaults to false. - - -PAPERLESS_CONSUMER_BARCODE_TIFF_SUPPORT= - Whether TIFF image files should be scanned for barcodes. - This will automatically convert any TIFF image(s) to pdfs for later - processing. - This only has an effect, if PAPERLESS_CONSUMER_ENABLE_BARCODES has been - enabled. - - Defaults to false. - -PAPERLESS_CONSUMER_BARCODE_STRING=PATCHT - Defines the string to be detected as a separator barcode. - If paperless is used with the PATCH-T separator pages, users - shouldn't change this. - - Defaults to "PATCHT" - -PAPERLESS_CONVERT_MEMORY_LIMIT= - On smaller systems, or even in the case of Very Large Documents, the consumer - may explode, complaining about how it's "unable to extend pixel cache". In - such cases, try setting this to a reasonably low value, like 32. The - default is to use whatever is necessary to do everything without writing to - disk, and units are in megabytes. - - For more information on how to use this value, you should search - the web for "MAGICK_MEMORY_LIMIT". - - Defaults to 0, which disables the limit. - -PAPERLESS_CONVERT_TMPDIR= - Similar to the memory limit, if you've got a small system and your OS mounts - /tmp as tmpfs, you should set this to a path that's on a physical disk, like - /home/your_user/tmp or something. ImageMagick will use this as scratch space - when crunching through very large documents. - - For more information on how to use this value, you should search - the web for "MAGICK_TMPDIR". - - Default is none, which disables the temporary directory. - -PAPERLESS_POST_CONSUME_SCRIPT= - After a document is consumed, Paperless can trigger an arbitrary script if - you like. This script will be passed a number of arguments for you to work - with. For more information, take a look at :ref:`advanced-post_consume_script`. - - The default is blank, which means nothing will be executed. - -PAPERLESS_FILENAME_DATE_ORDER= - Paperless will check the document text for document date information. - Use this setting to enable checking the document filename for date - information. The date order can be set to any option as specified in - https://dateparser.readthedocs.io/en/latest/settings.html#date-order. - The filename will be checked first, and if nothing is found, the document - text will be checked as normal. - - A date in a filename must have some separators (`.`, `-`, `/`, etc) - for it to be parsed. - - Defaults to none, which disables this feature. - -PAPERLESS_NUMBER_OF_SUGGESTED_DATES= - Paperless searches an entire document for dates. The first date found will - be used as the initial value for the created date. When this variable is - greater than 0 (or left to it's default value), paperless will also suggest - other dates found in the document, up to a maximum of this setting. Note that - duplicates will be removed, which can result in fewer dates displayed in the - frontend than this setting value. - - The task to find all dates can be time-consuming and increases with a higher - (maximum) number of suggested dates and slower hardware. - - Defaults to 3. Set to 0 to disable this feature. - -PAPERLESS_THUMBNAIL_FONT_NAME= - Paperless creates thumbnails for plain text files by rendering the content - of the file on an image and uses a predefined font for that. This - font can be changed here. - - Note that this won't have any effect on already generated thumbnails. - - Defaults to ``/usr/share/fonts/liberation/LiberationSerif-Regular.ttf``. - -PAPERLESS_IGNORE_DATES= - Paperless parses a documents creation date from filename and file content. - You may specify a comma separated list of dates that should be ignored during - this process. This is useful for special dates (like date of birth) that appear - in documents regularly but are very unlikely to be the documents creation date. - - The date is parsed using the order specified in PAPERLESS_DATE_ORDER - - Defaults to an empty string to not ignore any dates. - -PAPERLESS_DATE_ORDER= - Paperless will try to determine the document creation date from its contents. - Specify the date format Paperless should expect to see within your documents. - - This option defaults to DMY which translates to day first, month second, and year - last order. Characters D, M, or Y can be shuffled to meet the required order. - -PAPERLESS_CONSUMER_IGNORE_PATTERNS= - By default, paperless ignores certain files and folders in the consumption - directory, such as system files created by the Mac OS. - - This can be adjusted by configuring a custom json array with patterns to exclude. - - Defaults to ``[".DS_STORE/*", "._*", ".stfolder/*", ".stversions/*", ".localized/*", "desktop.ini"]``. - -Binaries -######## - -There are a few external software packages that Paperless expects to find on -your system when it starts up. Unless you've done something creative with -their installation, you probably won't need to edit any of these. However, -if you've installed these programs somewhere where simply typing the name of -the program doesn't automatically execute it (ie. the program isn't in your -$PATH), then you'll need to specify the literal path for that program. - -PAPERLESS_CONVERT_BINARY= - Defaults to "convert". - -PAPERLESS_GS_BINARY= - Defaults to "gs". - - -.. _configuration-docker: - -Docker-specific options -####################### - -These options don't have any effect in ``paperless.conf``. These options adjust -the behavior of the docker container. Configure these in `docker-compose.env`. - -PAPERLESS_WEBSERVER_WORKERS= - The number of worker processes the webserver should spawn. More worker processes - usually result in the front end to load data much quicker. However, each worker process - also loads the entire application into memory separately, so increasing this value - will increase RAM usage. - - Defaults to 1. - -PAPERLESS_BIND_ADDR= - The IP address the webserver will listen on inside the container. There are - special setups where you may need to configure this value to restrict the - Ip address or interface the webserver listens on. - - Defaults to [::], meaning all interfaces, including IPv6. - -PAPERLESS_PORT= - The port number the webserver will listen on inside the container. There are - special setups where you may need this to avoid collisions with other - services (like using podman with multiple containers in one pod). - - Don't change this when using Docker. To change the port the webserver is - reachable outside of the container, instead refer to the "ports" key in - ``docker-compose.yml``. - - Defaults to 8000. - -USERMAP_UID= - The ID of the paperless user in the container. Set this to your actual user ID on the - host system, which you can get by executing - - .. code:: shell-session - - $ id -u - - Paperless will change ownership on its folders to this user, so you need to get this right - in order to be able to write to the consumption directory. - - Defaults to 1000. - -USERMAP_GID= - The ID of the paperless Group in the container. Set this to your actual group ID on the - host system, which you can get by executing - - .. code:: shell-session - - $ id -g - - Paperless will change ownership on its folders to this group, so you need to get this right - in order to be able to write to the consumption directory. - - Defaults to 1000. - -PAPERLESS_OCR_LANGUAGES= - Additional OCR languages to install. By default, paperless comes with - English, German, Italian, Spanish and French. If your language is not in this list, install - additional languages with this configuration option: - - .. code:: bash - - PAPERLESS_OCR_LANGUAGES=tur ces - - To actually use these languages, also set the default OCR language of paperless: - - .. code:: bash - - PAPERLESS_OCR_LANGUAGE=tur - - Defaults to none, which does not install any additional languages. - -PAPERLESS_ENABLE_FLOWER= - If this environment variable is defined, the Celery monitoring tool - `Flower `_ will - be started by the container. - - You can read more about this in the :ref:`advanced setup ` - documentation. - - -.. _configuration-update-checking: - -Update Checking -############### - -PAPERLESS_ENABLE_UPDATE_CHECK= - - .. note:: - - This setting was deprecated in favor of a frontend setting after v1.9.2. A one-time - migration is performed for users who have this setting set. This setting is always - ignored if the corresponding frontend setting has been set. diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 000000000..3e6550fa1 --- /dev/null +++ b/docs/development.md @@ -0,0 +1,469 @@ +# Development + +This section describes the steps you need to take to start development +on paperless-ngx. + +Check out the source from github. The repository is organized in the +following way: + +- `main` always represents the latest release and will only see + changes when a new release is made. +- `dev` contains the code that will be in the next release. +- `feature-X` contain bigger changes that will be in some release, but + not necessarily the next one. + +When making functional changes to paperless, _always_ make your changes +on the `dev` branch. + +Apart from that, the folder structure is as follows: + +- `docs/` - Documentation. +- `src-ui/` - Code of the front end. +- `src/` - Code of the back end. +- `scripts/` - Various scripts that help with different parts of + development. +- `docker/` - Files required to build the docker image. + +## Contributing to Paperless + +Maybe you've been using Paperless for a while and want to add a feature +or two, or maybe you've come across a bug that you have some ideas how +to solve. The beauty of open source software is that you can see what's +wrong and help to get it fixed for everyone! + +Before contributing please review our [code of +conduct](https://github.com/paperless-ngx/paperless-ngx/blob/main/CODE_OF_CONDUCT.md) +and other important information in the [contributing +guidelines](https://github.com/paperless-ngx/paperless-ngx/blob/main/CONTRIBUTING.md). + +## Code formatting with pre-commit Hooks + +To ensure a consistent style and formatting across the project source, +the project utilizes a Git [pre-commit]{.title-ref} hook to perform some +formatting and linting before a commit is allowed. That way, everyone +uses the same style and some common issues can be caught early on. See +below for installation instructions. + +Once installed, hooks will run when you commit. If the formatting isn't +quite right or a linter catches something, the commit will be rejected. +You'll need to look at the output and fix the issue. Some hooks, such +as the Python formatting tool [black]{.title-ref}, will format failing +files, so all you need to do is [git add]{.title-ref} those files again +and retry your commit. + +## Initial setup and first start + +After you forked and cloned the code from github you need to perform a +first-time setup. To do the setup you need to perform the steps from the +following chapters in a certain order: + +1. Install prerequisites + pipenv as mentioned in + `[Bare metal route](/setup#bare_metal) + +2. Copy `paperless.conf.example` to `paperless.conf` and enable debug + mode. + +3. Install the Angular CLI interface: + + ```shell-session + $ npm install -g @angular/cli + ``` + +4. Install pre-commit + + ```shell-session + pre-commit install + ``` + +5. Create `consume` and `media` folders in the cloned root folder. + + ```shell-session + mkdir -p consume media + ``` + +6. You can now either \... + + - install redis or + + - use the included scripts/start-services.sh to use docker to fire + up a redis instance (and some other services such as tika, + gotenberg and a database server) or + + - spin up a bare redis container + + > ```shell-session + > docker run -d -p 6379:6379 --restart unless-stopped redis:latest + > ``` + +7. Install the python dependencies by performing in the src/ directory. + + ```shell-session + pipenv install --dev + ``` + +> - Make sure you're using python 3.9.x or lower. Otherwise you might +> get issues with building dependencies. You can use +> [pyenv](https://github.com/pyenv/pyenv) to install a specific +> python version. + +8. Generate the static UI so you can perform a login to get session + that is required for frontend development (this needs to be done one + time only). From src-ui directory: + + ```shell-session + npm install . + ./node_modules/.bin/ng build --configuration production + ``` + +9. Apply migrations and create a superuser for your dev instance: + + ```shell-session + python3 manage.py migrate + python3 manage.py createsuperuser + ``` + +10. Now spin up the dev backend. Depending on which part of paperless + you're developing for, you need to have some or all of them + running. + +> ```shell-session +> python3 manage.py runserver & python3 manage.py document_consumer & celery --app paperless worker +> ``` + +11. Login with the superuser credentials provided in step 8 at + `http://localhost:8000` to create a session that enables you to use + the backend. + +Backend development environment is now ready, to start Frontend +development go to `/src-ui` and run `ng serve`. From there you can use +`http://localhost:4200` for a preview. + +## Back end development + +The backend is a django application. PyCharm works well for development, +but you can use whatever you want. + +Configure the IDE to use the src/ folder as the base source folder. +Configure the following launch configurations in your IDE: + +- python3 manage.py runserver +- celery \--app paperless worker +- python3 manage.py document_consumer + +To start them all: + +```shell-session +python3 manage.py runserver & python3 manage.py document_consumer & celery --app paperless worker +``` + +Testing and code style: + +- Run `pytest` in the src/ directory to execute all tests. This also + generates a HTML coverage report. When runnings test, paperless.conf + is loaded as well. However: the tests rely on the default + configuration. This is not ideal. But for now, make sure no settings + except for DEBUG are overridden when testing. + +- Coding style is enforced by the Git pre-commit hooks. These will + ensure your code is formatted and do some linting when you do a [git + commit]{.title-ref}. + +- You can also run `black` manually to format your code + + !!! note + + The line length rule E501 is generally useful for getting multiple + source files next to each other on the screen. However, in some + cases, its just not possible to make some lines fit, especially + complicated IF cases. Append `# NOQA: E501` to disable this check + for certain lines. + +## Front end development + +The front end is built using Angular. In order to get started, you need +`npm`. Install the Angular CLI interface with + +```shell-session +$ npm install -g @angular/cli +``` + +and make sure that it's on your path. Next, in the src-ui/ directory, +install the required dependencies of the project. + +```shell-session +$ npm install +``` + +You can launch a development server by running + +```shell-session +$ ng serve +``` + +This will automatically update whenever you save. However, in-place +compilation might fail on syntax errors, in which case you need to +restart it. + +By default, the development server is available on +`http://localhost:4200/` and is configured to access the API at +`http://localhost:8000/api/`, which is the default of the backend. If +you enabled DEBUG on the back end, several security overrides for +allowed hosts, CORS and X-Frame-Options are in place so that the front +end behaves exactly as in production. This also relies on you being +logged into the back end. Without a valid session, The front end will +simply not work. + +Testing and code style: + +- The frontend code (.ts, .html, .scss) use `prettier` for code + formatting via the Git `pre-commit` hooks which run automatically on + commit. See + [above](#code-formatting-with-pre-commit-hooks) for installation. You can also run this via cli with a + command such as + + ```shell-session + $ git ls-files -- '*.ts' | xargs pre-commit run prettier --files + ``` + +- Frontend testing uses jest and cypress. There is currently a need + for significantly more frontend tests. Unit tests and e2e tests, + respectively, can be run non-interactively with: + + ```shell-session + $ ng test + $ npm run e2e:ci + ``` + + Cypress also includes a UI which can be run from within the `src-ui` + directory with + + ```shell-session + $ ./node_modules/.bin/cypress open + ``` + +In order to build the front end and serve it as part of django, execute + +```shell-session +$ ng build --prod +``` + +This will build the front end and put it in a location from which the +Django server will serve it as static content. This way, you can verify +that authentication is working. + +## Localization + +Paperless is available in many different languages. Since paperless +consists both of a django application and an Angular front end, both +these parts have to be translated separately. + +### Front end localization + +- The Angular front end does localization according to the [Angular + documentation](https://angular.io/guide/i18n). +- The source language of the project is "en_US". +- The source strings end up in the file "src-ui/messages.xlf". +- The translated strings need to be placed in the + "src-ui/src/locale/" folder. +- In order to extract added or changed strings from the source files, + call `ng xi18n --ivy`. + +Adding new languages requires adding the translated files in the +"src-ui/src/locale/" folder and adjusting a couple files. + +1. Adjust "src-ui/angular.json": + + ```json + "i18n": { + "sourceLocale": "en-US", + "locales": { + "de": "src/locale/messages.de.xlf", + "nl-NL": "src/locale/messages.nl_NL.xlf", + "fr": "src/locale/messages.fr.xlf", + "en-GB": "src/locale/messages.en_GB.xlf", + "pt-BR": "src/locale/messages.pt_BR.xlf", + "language-code": "language-file" + } + } + ``` + +2. Add the language to the available options in + "src-ui/src/app/services/settings.service.ts": + + ```typescript + getLanguageOptions(): LanguageOption[] { + return [ + {code: "en-us", name: $localize`English (US)`, englishName: "English (US)", dateInputFormat: "mm/dd/yyyy"}, + {code: "en-gb", name: $localize`English (GB)`, englishName: "English (GB)", dateInputFormat: "dd/mm/yyyy"}, + {code: "de", name: $localize`German`, englishName: "German", dateInputFormat: "dd.mm.yyyy"}, + {code: "nl", name: $localize`Dutch`, englishName: "Dutch", dateInputFormat: "dd-mm-yyyy"}, + {code: "fr", name: $localize`French`, englishName: "French", dateInputFormat: "dd/mm/yyyy"}, + {code: "pt-br", name: $localize`Portuguese (Brazil)`, englishName: "Portuguese (Brazil)", dateInputFormat: "dd/mm/yyyy"} + // Add your new language here + ] + } + ``` + + `dateInputFormat` is a special string that defines the behavior of + the date input fields and absolutely needs to contain "dd", "mm" + and "yyyy". + +3. Import and register the Angular data for this locale in + "src-ui/src/app/app.module.ts": + + ```typescript + import localeDe from '@angular/common/locales/de' + registerLocaleData(localeDe) + ``` + +### Back end localization + +A majority of the strings that appear in the back end appear only when +the admin is used. However, some of these are still shown on the front +end (such as error messages). + +- The django application does localization according to the [django + documentation](https://docs.djangoproject.com/en/3.1/topics/i18n/translation/). +- The source language of the project is "en_US". +- Localization files end up in the folder "src/locale/". +- In order to extract strings from the application, call + `python3 manage.py makemessages -l en_US`. This is important after + making changes to translatable strings. +- The message files need to be compiled for them to show up in the + application. Call `python3 manage.py compilemessages` to do this. + The generated files don't get committed into git, since these are + derived artifacts. The build pipeline takes care of executing this + command. + +Adding new languages requires adding the translated files in the +"src/locale/" folder and adjusting the file +"src/paperless/settings.py" to include the new language: + +```python +LANGUAGES = [ + ("en-us", _("English (US)")), + ("en-gb", _("English (GB)")), + ("de", _("German")), + ("nl-nl", _("Dutch")), + ("fr", _("French")), + ("pt-br", _("Portuguese (Brazil)")), + # Add language here. +] +``` + +## Building the documentation + +The documentation is built using material-mkdocs, see their [documentation](https://squidfunk.github.io/mkdocs-material/reference/). If you want to build the documentation locally, this is how you do it: + +1. Install python dependencies. + + ```shell-session + $ cd /path/to/paperless + $ pipenv install --dev + ``` + +2. Build the documentation + + ```shell-session + $ cd /path/to/paperless + $ pipenv mkdocs build + ``` + +## Building the Docker image + +The docker image is primarily built by the GitHub actions workflow, but +it can be faster when developing to build and tag an image locally. + +To provide the build arguments automatically, build the image using the +helper script `build-docker-image.sh`. + +Building the docker image from source: + +> ```shell-session +> ./build-docker-image.sh Dockerfile -t +> ``` + +## Extending Paperless + +Paperless does not have any fancy plugin systems and will probably never +have. However, some parts of the application have been designed to allow +easy integration of additional features without any modification to the +base code. + +### Making custom parsers + +Paperless uses parsers to add documents to paperless. A parser is +responsible for: + +- Retrieve the content from the original +- Create a thumbnail +- Optional: Retrieve a created date from the original +- Optional: Create an archived document from the original + +Custom parsers can be added to paperless to support more file types. In +order to do that, you need to write the parser itself and announce its +existence to paperless. + +The parser itself must extend `documents.parsers.DocumentParser` and +must implement the methods `parse` and `get_thumbnail`. You can provide +your own implementation to `get_date` if you don't want to rely on +paperless' default date guessing mechanisms. + +```python +class MyCustomParser(DocumentParser): + + def parse(self, document_path, mime_type): + # This method does not return anything. Rather, you should assign + # whatever you got from the document to the following fields: + + # The content of the document. + self.text = "content" + + # Optional: path to a PDF document that you created from the original. + self.archive_path = os.path.join(self.tempdir, "archived.pdf") + + # Optional: "created" date of the document. + self.date = get_created_from_metadata(document_path) + + def get_thumbnail(self, document_path, mime_type): + # This should return the path to a thumbnail you created for this + # document. + return os.path.join(self.tempdir, "thumb.png") +``` + +If you encounter any issues during parsing, raise a +`documents.parsers.ParseError`. + +The `self.tempdir` directory is a temporary directory that is guaranteed +to be empty and removed after consumption finished. You can use that +directory to store any intermediate files and also use it to store the +thumbnail / archived document. + +After that, you need to announce your parser to paperless. You need to +connect a handler to the `document_consumer_declaration` signal. Have a +look in the file `src/paperless_tesseract/apps.py` on how that's done. +The handler is a method that returns information about your parser: + +```python +def myparser_consumer_declaration(sender, **kwargs): + return { + "parser": MyCustomParser, + "weight": 0, + "mime_types": { + "application/pdf": ".pdf", + "image/jpeg": ".jpg", + } + } +``` + +- `parser` is a reference to a class that extends `DocumentParser`. +- `weight` is used whenever two or more parsers are able to parse a + file: The parser with the higher weight wins. This can be used to + override the parsers provided by paperless. +- `mime_types` is a dictionary. The keys are the mime types your + parser supports and the value is the default file extension that + paperless should use when storing files and serving them for + download. We could guess that from the file extensions, but some + mime types have many extensions associated with them and the python + methods responsible for guessing the extension do not always return + the same value. diff --git a/docs/extending.rst b/docs/extending.rst deleted file mode 100644 index e8126fd4d..000000000 --- a/docs/extending.rst +++ /dev/null @@ -1,431 +0,0 @@ -.. _extending: - -Paperless-ngx Development -######################### - -This section describes the steps you need to take to start development on paperless-ngx. - -Check out the source from github. The repository is organized in the following way: - -* ``main`` always represents the latest release and will only see changes - when a new release is made. -* ``dev`` contains the code that will be in the next release. -* ``feature-X`` contain bigger changes that will be in some release, but not - necessarily the next one. - -When making functional changes to paperless, *always* make your changes on the ``dev`` branch. - -Apart from that, the folder structure is as follows: - -* ``docs/`` - Documentation. -* ``src-ui/`` - Code of the front end. -* ``src/`` - Code of the back end. -* ``scripts/`` - Various scripts that help with different parts of development. -* ``docker/`` - Files required to build the docker image. - -Contributing to Paperless -========================= - -Maybe you've been using Paperless for a while and want to add a feature or two, -or maybe you've come across a bug that you have some ideas how to solve. The -beauty of open source software is that you can see what's wrong and help to get -it fixed for everyone! - -Before contributing please review our `code of conduct`_ and other important -information in the `contributing guidelines`_. - -.. _code-formatting-with-pre-commit-hooks: - -Code formatting with pre-commit Hooks -===================================== - -To ensure a consistent style and formatting across the project source, the project -utilizes a Git `pre-commit` hook to perform some formatting and linting before a -commit is allowed. That way, everyone uses the same style and some common issues -can be caught early on. See below for installation instructions. - -Once installed, hooks will run when you commit. If the formatting isn't quite right -or a linter catches something, the commit will be rejected. You'll need to look at the -output and fix the issue. Some hooks, such as the Python formatting tool `black`, -will format failing files, so all you need to do is `git add` those files again and -retry your commit. - -Initial setup and first start -============================= - -After you forked and cloned the code from github you need to perform a first-time setup. -To do the setup you need to perform the steps from the following chapters in a certain order: - -1. Install prerequisites + pipenv as mentioned in :ref:`Bare metal route ` -2. Copy ``paperless.conf.example`` to ``paperless.conf`` and enable debug mode. -3. Install the Angular CLI interface: - - .. code:: shell-session - - $ npm install -g @angular/cli - -4. Install pre-commit - - .. code:: shell-session - - pre-commit install - -5. Create ``consume`` and ``media`` folders in the cloned root folder. - - .. code:: shell-session - - mkdir -p consume media - -6. You can now either ... - - * install redis or - * use the included scripts/start-services.sh to use docker to fire up a redis instance (and some other services such as tika, gotenberg and a database server) or - * spin up a bare redis container - - .. code:: shell-session - - docker run -d -p 6379:6379 --restart unless-stopped redis:latest - -7. Install the python dependencies by performing in the src/ directory. - - .. code:: shell-session - - pipenv install --dev - - * Make sure you're using python 3.9.x or lower. Otherwise you might get issues with building dependencies. You can use `pyenv `_ to install a specific python version. - -8. Generate the static UI so you can perform a login to get session that is required for frontend development (this needs to be done one time only). From src-ui directory: - - .. code:: shell-session - - npm install . - ./node_modules/.bin/ng build --configuration production - -9. Apply migrations and create a superuser for your dev instance: - - .. code:: shell-session - - python3 manage.py migrate - python3 manage.py createsuperuser - -10. Now spin up the dev backend. Depending on which part of paperless you're developing for, you need to have some or all of them running. - - .. code:: shell-session - - python3 manage.py runserver & python3 manage.py document_consumer & celery --app paperless worker - -11. Login with the superuser credentials provided in step 8 at ``http://localhost:8000`` to create a session that enables you to use the backend. - -Backend development environment is now ready, to start Frontend development go to ``/src-ui`` and run ``ng serve``. From there you can use ``http://localhost:4200`` for a preview. - -Back end development -==================== - -The backend is a django application. PyCharm works well for development, but you can use whatever -you want. - -Configure the IDE to use the src/ folder as the base source folder. Configure the following -launch configurations in your IDE: - -* python3 manage.py runserver -* celery --app paperless worker -* python3 manage.py document_consumer - -To start them all: - -.. code:: shell-session - - python3 manage.py runserver & python3 manage.py document_consumer & celery --app paperless worker - -Testing and code style: - -* Run ``pytest`` in the src/ directory to execute all tests. This also generates a HTML coverage - report. When runnings test, paperless.conf is loaded as well. However: the tests rely on the default - configuration. This is not ideal. But for now, make sure no settings except for DEBUG are overridden when testing. -* Coding style is enforced by the Git pre-commit hooks. These will ensure your code is formatted and do some - linting when you do a `git commit`. -* You can also run ``black`` manually to format your code - - .. note:: - - The line length rule E501 is generally useful for getting multiple source files - next to each other on the screen. However, in some cases, its just not possible - to make some lines fit, especially complicated IF cases. Append ``# NOQA: E501`` - to disable this check for certain lines. - -Front end development -===================== - -The front end is built using Angular. In order to get started, you need ``npm``. -Install the Angular CLI interface with - -.. code:: shell-session - - $ npm install -g @angular/cli - -and make sure that it's on your path. Next, in the src-ui/ directory, install the -required dependencies of the project. - -.. code:: shell-session - - $ npm install - -You can launch a development server by running - -.. code:: shell-session - - $ ng serve - -This will automatically update whenever you save. However, in-place compilation might fail -on syntax errors, in which case you need to restart it. - -By default, the development server is available on ``http://localhost:4200/`` and is configured -to access the API at ``http://localhost:8000/api/``, which is the default of the backend. -If you enabled DEBUG on the back end, several security overrides for allowed hosts, CORS and -X-Frame-Options are in place so that the front end behaves exactly as in production. This also -relies on you being logged into the back end. Without a valid session, The front end will simply -not work. - -Testing and code style: - -* The frontend code (.ts, .html, .scss) use ``prettier`` for code formatting via the Git - ``pre-commit`` hooks which run automatically on commit. See - :ref:`above ` for installation. You can also run this - via cli with a command such as - - .. code:: shell-session - - $ git ls-files -- '*.ts' | xargs pre-commit run prettier --files - -* Frontend testing uses jest and cypress. There is currently a need for significantly more - frontend tests. Unit tests and e2e tests, respectively, can be run non-interactively with: - - .. code:: shell-session - - $ ng test - $ npm run e2e:ci - - Cypress also includes a UI which can be run from within the ``src-ui`` directory with - - .. code:: shell-session - - $ ./node_modules/.bin/cypress open - -In order to build the front end and serve it as part of django, execute - -.. code:: shell-session - - $ ng build --prod - -This will build the front end and put it in a location from which the Django server will serve -it as static content. This way, you can verify that authentication is working. - - -Localization -============ - -Paperless is available in many different languages. Since paperless consists both of a django -application and an Angular front end, both these parts have to be translated separately. - -Front end localization ----------------------- - -* The Angular front end does localization according to the `Angular documentation `_. -* The source language of the project is "en_US". -* The source strings end up in the file "src-ui/messages.xlf". -* The translated strings need to be placed in the "src-ui/src/locale/" folder. -* In order to extract added or changed strings from the source files, call ``ng xi18n --ivy``. - -Adding new languages requires adding the translated files in the "src-ui/src/locale/" folder and adjusting a couple files. - -1. Adjust "src-ui/angular.json": - - .. code:: json - - "i18n": { - "sourceLocale": "en-US", - "locales": { - "de": "src/locale/messages.de.xlf", - "nl-NL": "src/locale/messages.nl_NL.xlf", - "fr": "src/locale/messages.fr.xlf", - "en-GB": "src/locale/messages.en_GB.xlf", - "pt-BR": "src/locale/messages.pt_BR.xlf", - "language-code": "language-file" - } - } - -2. Add the language to the available options in "src-ui/src/app/services/settings.service.ts": - - .. code:: typescript - - getLanguageOptions(): LanguageOption[] { - return [ - {code: "en-us", name: $localize`English (US)`, englishName: "English (US)", dateInputFormat: "mm/dd/yyyy"}, - {code: "en-gb", name: $localize`English (GB)`, englishName: "English (GB)", dateInputFormat: "dd/mm/yyyy"}, - {code: "de", name: $localize`German`, englishName: "German", dateInputFormat: "dd.mm.yyyy"}, - {code: "nl", name: $localize`Dutch`, englishName: "Dutch", dateInputFormat: "dd-mm-yyyy"}, - {code: "fr", name: $localize`French`, englishName: "French", dateInputFormat: "dd/mm/yyyy"}, - {code: "pt-br", name: $localize`Portuguese (Brazil)`, englishName: "Portuguese (Brazil)", dateInputFormat: "dd/mm/yyyy"} - // Add your new language here - ] - } - - ``dateInputFormat`` is a special string that defines the behavior of the date input fields and absolutely needs to contain "dd", "mm" and "yyyy". - -3. Import and register the Angular data for this locale in "src-ui/src/app/app.module.ts": - - .. code:: typescript - - import localeDe from '@angular/common/locales/de'; - registerLocaleData(localeDe) - -Back end localization ---------------------- - -A majority of the strings that appear in the back end appear only when the admin is used. However, -some of these are still shown on the front end (such as error messages). - -* The django application does localization according to the `django documentation `_. -* The source language of the project is "en_US". -* Localization files end up in the folder "src/locale/". -* In order to extract strings from the application, call ``python3 manage.py makemessages -l en_US``. This is important after making changes to translatable strings. -* The message files need to be compiled for them to show up in the application. Call ``python3 manage.py compilemessages`` to do this. The generated files don't get - committed into git, since these are derived artifacts. The build pipeline takes care of executing this command. - -Adding new languages requires adding the translated files in the "src/locale/" folder and adjusting the file "src/paperless/settings.py" to include the new language: - -.. code:: python - - LANGUAGES = [ - ("en-us", _("English (US)")), - ("en-gb", _("English (GB)")), - ("de", _("German")), - ("nl-nl", _("Dutch")), - ("fr", _("French")), - ("pt-br", _("Portuguese (Brazil)")), - # Add language here. - ] - - -Building the documentation -========================== - -The documentation is built using sphinx. I've configured ReadTheDocs to automatically build -the documentation when changes are pushed. If you want to build the documentation locally, -this is how you do it: - -1. Install python dependencies. - - .. code:: shell-session - - $ cd /path/to/paperless - $ pipenv install --dev - -2. Build the documentation - - .. code:: shell-session - - $ cd /path/to/paperless/docs - $ pipenv run make clean html - -This will build the HTML documentation, and put the resulting files in the ``_build/html`` -directory. - -Building the Docker image -========================= - -The docker image is primarily built by the GitHub actions workflow, but it can be -faster when developing to build and tag an image locally. - -To provide the build arguments automatically, build the image using the helper -script ``build-docker-image.sh``. - -Building the docker image from source: - - .. code:: shell-session - - ./build-docker-image.sh Dockerfile -t - -Extending Paperless -=================== - -Paperless does not have any fancy plugin systems and will probably never have. However, -some parts of the application have been designed to allow easy integration of additional -features without any modification to the base code. - -Making custom parsers ---------------------- - -Paperless uses parsers to add documents to paperless. A parser is responsible for: - -* Retrieve the content from the original -* Create a thumbnail -* Optional: Retrieve a created date from the original -* Optional: Create an archived document from the original - -Custom parsers can be added to paperless to support more file types. In order to do that, -you need to write the parser itself and announce its existence to paperless. - -The parser itself must extend ``documents.parsers.DocumentParser`` and must implement the -methods ``parse`` and ``get_thumbnail``. You can provide your own implementation to -``get_date`` if you don't want to rely on paperless' default date guessing mechanisms. - -.. code:: python - - class MyCustomParser(DocumentParser): - - def parse(self, document_path, mime_type): - # This method does not return anything. Rather, you should assign - # whatever you got from the document to the following fields: - - # The content of the document. - self.text = "content" - - # Optional: path to a PDF document that you created from the original. - self.archive_path = os.path.join(self.tempdir, "archived.pdf") - - # Optional: "created" date of the document. - self.date = get_created_from_metadata(document_path) - - def get_thumbnail(self, document_path, mime_type): - # This should return the path to a thumbnail you created for this - # document. - return os.path.join(self.tempdir, "thumb.png") - -If you encounter any issues during parsing, raise a ``documents.parsers.ParseError``. - -The ``self.tempdir`` directory is a temporary directory that is guaranteed to be empty -and removed after consumption finished. You can use that directory to store any -intermediate files and also use it to store the thumbnail / archived document. - -After that, you need to announce your parser to paperless. You need to connect a -handler to the ``document_consumer_declaration`` signal. Have a look in the file -``src/paperless_tesseract/apps.py`` on how that's done. The handler is a method -that returns information about your parser: - -.. code:: python - - def myparser_consumer_declaration(sender, **kwargs): - return { - "parser": MyCustomParser, - "weight": 0, - "mime_types": { - "application/pdf": ".pdf", - "image/jpeg": ".jpg", - } - } - -* ``parser`` is a reference to a class that extends ``DocumentParser``. - -* ``weight`` is used whenever two or more parsers are able to parse a file: The parser with - the higher weight wins. This can be used to override the parsers provided by - paperless. - -* ``mime_types`` is a dictionary. The keys are the mime types your parser supports and the value - is the default file extension that paperless should use when storing files and serving them for - download. We could guess that from the file extensions, but some mime types have many extensions - associated with them and the python methods responsible for guessing the extension do not always - return the same value. - -.. _code of conduct: https://github.com/paperless-ngx/paperless-ngx/blob/main/CODE_OF_CONDUCT.md -.. _contributing guidelines: https://github.com/paperless-ngx/paperless-ngx/blob/main/CONTRIBUTING.md diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 000000000..ac8345579 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,125 @@ +# Frequently Asked Questions + +### _What's the general plan for Paperless-ngx?_ + +**A:** While Paperless-ngx is already considered largely +"feature-complete" it is a community-driven project and development +will be guided in this way. New features can be submitted via GitHub +discussions and "up-voted" by the community but this is not a +guarantee the feature will be implemented. This project will always be +open to collaboration in the form of PRs, ideas etc. + +### _I'm using docker. Where are my documents?_ + +**A:** Your documents are stored inside the docker volume +`paperless_media`. Docker manages this volume automatically for you. It +is a persistent storage and will persist as long as you don't +explicitly delete it. The actual location depends on your host operating +system. On Linux, chances are high that this location is + +``` +/var/lib/docker/volumes/paperless_media/_data +``` + +!!! warning + + Do not mess with this folder. Don't change permissions and don't move + files around manually. This folder is meant to be entirely managed by + docker and paperless. + +### Let's say I want to switch tools in a year. Can I easily move + +to other systems?\* + +**A:** Your documents are stored as plain files inside the media folder. +You can always drag those files out of that folder to use them +elsewhere. Here are a couple notes about that. + +- Paperless-ngx never modifies your original documents. It keeps + checksums of all documents and uses a scheduled sanity checker to + check that they remain the same. +- By default, paperless uses the internal ID of each document as its + filename. This might not be very convenient for export. However, you + can adjust the way files are stored in paperless by + [configuring the filename format](advanced_usage#file_name_handling). +- [The exporter](administration#exporter) is + another easy way to get your files out of paperless with reasonable + file names. + +### _What file types does paperless-ngx support?_ + +**A:** Currently, the following files are supported: + +- PDF documents, PNG images, JPEG images, TIFF images and GIF images + are processed with OCR and converted into PDF documents. +- Plain text documents are supported as well and are added verbatim to + paperless. +- With the optional Tika integration enabled (see [Tika configuration](configuration#tika), + Paperless also supports various Office documents (.docx, .doc, odt, + .ppt, .pptx, .odp, .xls, .xlsx, .ods). + +Paperless-ngx determines the type of a file by inspecting its content. +The file extensions do not matter. + +### _Will paperless-ngx run on Raspberry Pi?_ + +**A:** The short answer is yes. I've tested it on a Raspberry Pi 3 B. +The long answer is that certain parts of Paperless will run very slow, +such as the OCR. On Raspberry Pi, try to OCR documents before feeding +them into paperless so that paperless can reuse the text. The web +interface is a lot snappier, since it runs in your browser and paperless +has to do much less work to serve the data. + +!!! note + + You can adjust some of the settings so that paperless uses less + processing power. See [setup](setup#less_powerful_devices) for details. + +### _How do I install paperless-ngx on Raspberry Pi?_ + +**A:** Docker images are available for arm and arm64 hardware, so just +follow the docker-compose instructions. Apart from more required disk +space compared to a bare metal installation, docker comes with close to +zero overhead, even on Raspberry Pi. + +If you decide to got with the bare metal route, be aware that some of +the python requirements do not have precompiled packages for ARM / +ARM64. Installation of these will require additional development +libraries and compilation will take a long time. + +### _How do I run this on Unraid?_ + +**A:** Paperless-ngx is available as [community +app](https://unraid.net/community/apps?q=paperless-ngx) in Unraid. [Uli +Fahrer](https://github.com/Tooa) created a container template for that. + +### _How do I run this on my toaster?_ + +**A:** I honestly don't know! As for all other devices that might be +able to run paperless, you're a bit on your own. If you can't run the +docker image, the documentation has instructions for bare metal +installs. I'm running paperless on an i3 processor from 2015 or so. +This is also what I use to test new releases with. Apart from that, I +also have a Raspberry Pi, which I occasionally build the image on and +see if it works. + +### _How do I proxy this with NGINX?_ + +**A:** See [here](setup#nginx). + +### _How do I get WebSocket support with Apache mod_wsgi_? + +**A:** `mod_wsgi` by itself does not support ASGI. Paperless will +continue to work with WSGI, but certain features such as status +notifications about document consumption won't be available. + +If you want to continue using `mod_wsgi`, you will have to run an +ASGI-enabled web server as well that processes WebSocket connections, +and configure Apache to redirect WebSocket connections to this server. +Multiple options for ASGI servers exist: + +- `gunicorn` with `uvicorn` as the worker implementation (the default + of paperless) +- `daphne` as a standalone server, which is the reference + implementation for ASGI. +- `uvicorn` as a standalone server diff --git a/docs/faq.rst b/docs/faq.rst deleted file mode 100644 index 1b2892fc3..000000000 --- a/docs/faq.rst +++ /dev/null @@ -1,117 +0,0 @@ - -************************** -Frequently asked questions -************************** - -**Q:** *What's the general plan for Paperless-ngx?* - -**A:** While Paperless-ngx is already considered largely "feature-complete" it is a community-driven -project and development will be guided in this way. New features can be submitted via -GitHub discussions and "up-voted" by the community but this is not a guarantee the feature -will be implemented. This project will always be open to collaboration in the form of PRs, -ideas etc. - -**Q:** *I'm using docker. Where are my documents?* - -**A:** Your documents are stored inside the docker volume ``paperless_media``. -Docker manages this volume automatically for you. It is a persistent storage -and will persist as long as you don't explicitly delete it. The actual location -depends on your host operating system. On Linux, chances are high that this location -is - -.. code:: - - /var/lib/docker/volumes/paperless_media/_data - -.. caution:: - - Do not mess with this folder. Don't change permissions and don't move - files around manually. This folder is meant to be entirely managed by docker - and paperless. - -**Q:** *Let's say I want to switch tools in a year. Can I easily move to other systems?* - -**A:** Your documents are stored as plain files inside the media folder. You can always drag those files -out of that folder to use them elsewhere. Here are a couple notes about that. - -* Paperless-ngx never modifies your original documents. It keeps checksums of all documents and uses a - scheduled sanity checker to check that they remain the same. -* By default, paperless uses the internal ID of each document as its filename. This might not be very - convenient for export. However, you can adjust the way files are stored in paperless by - :ref:`configuring the filename format `. -* :ref:`The exporter ` is another easy way to get your files out of paperless with reasonable file names. - -**Q:** *What file types does paperless-ngx support?* - -**A:** Currently, the following files are supported: - -* PDF documents, PNG images, JPEG images, TIFF images and GIF images are processed with OCR and converted into PDF documents. -* Plain text documents are supported as well and are added verbatim - to paperless. -* With the optional Tika integration enabled (see :ref:`Configuration `), Paperless also supports various - Office documents (.docx, .doc, odt, .ppt, .pptx, .odp, .xls, .xlsx, .ods). - -Paperless-ngx determines the type of a file by inspecting its content. The -file extensions do not matter. - -**Q:** *Will paperless-ngx run on Raspberry Pi?* - -**A:** The short answer is yes. I've tested it on a Raspberry Pi 3 B. -The long answer is that certain parts of -Paperless will run very slow, such as the OCR. On Raspberry Pi, -try to OCR documents before feeding them into paperless so that paperless can -reuse the text. The web interface is a lot snappier, since it runs -in your browser and paperless has to do much less work to serve the data. - -.. note:: - - You can adjust some of the settings so that paperless uses less processing - power. See :ref:`setup-less_powerful_devices` for details. - - -**Q:** *How do I install paperless-ngx on Raspberry Pi?* - -**A:** Docker images are available for arm and arm64 hardware, so just follow -the docker-compose instructions. Apart from more required disk space compared to -a bare metal installation, docker comes with close to zero overhead, even on -Raspberry Pi. - -If you decide to got with the bare metal route, be aware that some of the -python requirements do not have precompiled packages for ARM / ARM64. Installation -of these will require additional development libraries and compilation will take -a long time. - -**Q:** *How do I run this on Unraid?* - -**A:** Paperless-ngx is available as `community app `_ -in Unraid. `Uli Fahrer `_ created a container template for that. - -**Q:** *How do I run this on my toaster?* - -**A:** I honestly don't know! As for all other devices that might be able -to run paperless, you're a bit on your own. If you can't run the docker image, -the documentation has instructions for bare metal installs. I'm running -paperless on an i3 processor from 2015 or so. This is also what I use to test -new releases with. Apart from that, I also have a Raspberry Pi, which I -occasionally build the image on and see if it works. - -**Q:** *How do I proxy this with NGINX?* - -**A:** See :ref:`here `. - -.. _faq-mod_wsgi: - -**Q:** *How do I get WebSocket support with Apache mod_wsgi*? - -**A:** ``mod_wsgi`` by itself does not support ASGI. Paperless will continue -to work with WSGI, but certain features such as status notifications about -document consumption won't be available. - -If you want to continue using ``mod_wsgi``, you will have to run an ASGI-enabled -web server as well that processes WebSocket connections, and configure Apache to -redirect WebSocket connections to this server. Multiple options for ASGI servers -exist: - -* ``gunicorn`` with ``uvicorn`` as the worker implementation (the default of paperless) -* ``daphne`` as a standalone server, which is the reference implementation for ASGI. -* ``uvicorn`` as a standalone server diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..75a09b229 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,138 @@ +
    +![image](assets/logo_full_black.svg#only-light){.index-logo} +![image](assets/logo_full_white.svg#only-dark){.index-logo} + +**Paperless-ngx** is a _community-supported_ open-source document management system that transforms your +physical documents into a searchable online archive so you can keep, well, _less paper_. + +[Get started](/setup/){ .md-button .md-button--primary .index-callout } +[Demo](https://demo.paperless-ngx.com){ .md-button .md-button--secondary target=\_blank } + +
    +
    +![image](assets/screenshots/documents-smallcards.png#only-light){.index-screenshot} +![image](assets/screenshots/documents-smallcards-dark.png#only-dark){.index-screenshot} +
    +
    + +## Why This Exists + +Paper is a nightmare. Environmental issues aside, there's no excuse for +it in the 21st century. It takes up space, collects dust, doesn't +support any form of a search feature, indexing is tedious, it's heavy +and prone to damage & loss. + +This software is designed to make "going paperless" easier. No more worrying +about finding stuff again, feed documents right from the post box into +the scanner and then shred them. Perhaps you might find it useful too. + +## Paperless, a history + +Paperless is a simple Django application running in two parts: a +_Consumer_ (the thing that does the indexing) and the _Web server_ (the +part that lets you search & download already-indexed documents). If you +want to learn more about its functions keep on reading after the +installation section. + +Paperless-ngx is a document management system that transforms your +physical documents into a searchable online archive so you can keep, +well, _less paper_. + +Paperless-ngx forked from paperless-ng to continue the great work and +distribute responsibility of supporting and advancing the project among +a team of people. + +NG stands for both Angular (the framework used for the Frontend) and +next-gen. Publishing this project under a different name also avoids +confusion between paperless and paperless-ngx. + +If you want to learn about what's different in paperless-ngx from +Paperless, check out these resources in the documentation: + +- [Some screenshots](#screenshots) of the new UI are available. +- Read [this section](/advanced_usage/#advanced-automatic_matching) if you want to learn about how paperless automates all + tagging using machine learning. +- Paperless now comes with a [proper email consumer](/usage/#usage-email) that's fully tested and production ready. +- Paperless creates searchable PDF/A documents from whatever you put into the consumption directory. This means + that you can select text in image-only documents coming from your scanner. +- See [this note](/administration/#utilities-encyption) about GnuPG encryption in paperless-ngx. +- Paperless is now integrated with a + [task processing queue](/setup#task_processor) that tells you at a glance when and why something is not working. +- The [changelog](/changelog) contains a detailed list of all changes in paperless-ngx. + +## Screenshots + +This is what Paperless-ngx looks like. + +The dashboard shows customizable views on your document and allows +document uploads: + +[![image](assets/screenshots/dashboard.png)](assets/screenshots/dashboard.png) + +The document list provides three different styles to scroll through your +documents: + +[![image](assets/screenshots/documents-table.png)](assets/screenshots/documents-table.png) + +[![image](assets/screenshots/documents-smallcards.png)](assets/screenshots/documents-smallcards.png) + +[![image](assets/screenshots/documents-largecards.png)](assets/screenshots/documents-largecards.png) + +Paperless-ngx also supports dark mode: + +[![image](assets/screenshots/documents-smallcards-dark.png)](assets/screenshots/documents-smallcards-dark.png) + +Extensive filtering mechanisms: + +[![image](assets/screenshots/documents-filter.png)](assets/screenshots/documents-filter.png) + +Bulk editing of document tags, correspondents, etc.: + +[![image](assets/screenshots/bulk-edit.png)](assets/screenshots/bulk-edit.png) + +Side-by-side editing of documents: + +[![image](assets/screenshots/editing.png)](assets/screenshots/editing.png) + +Tag editing. This looks about the same for correspondents and document +types. + +[![image](assets/screenshots/new-tag.png)](assets/screenshots/new-tag.png) + +Searching provides auto complete and highlights the results. + +[![image](assets/screenshots/search-preview.png)](assets/screenshots/search-preview.png) + +[![image](assets/screenshots/search-results.png)](assets/screenshots/search-results.png) + +Fancy mail filters! + +[![image](assets/screenshots/mail-rules-edited.png)](assets/screenshots/mail-rules-edited.png) + +Mobile devices are supported. + +[![image](assets/screenshots/mobile.png)](assets/screenshots/mobile.png) + +## Support + +Community support is available via [GitHub Discussions](https://github.com/paperless-ngx/paperless-ngx/discussions/) and [the Matrix chat room](https://matrix.to/#/#paperless:matrix.org). + +### Feature Requests + +Feature requests can be submitted via [GitHub Discussions](https://github.com/paperless-ngx/paperless-ngx/discussions/categories/feature-requests) where you can search for existing ideas, add your own and vote for the ones you care about. + +### Bugs + +For bugs please [open an issue](https://github.com/paperless-ngx/paperless-ngx/issues) or [start a discussion](https://github.com/paperless-ngx/paperless-ngx/discussions/categories/support) if you have questions. + +## Contributing + +People interested in continuing the work on paperless-ngx are encouraged to reach out on [GitHub](https://github.com/paperless-ngx/paperless-ngx) or [the Matrix chat room](https://matrix.to/#/#paperless:matrix.org). If you would like to contribute to the project on an ongoing basis there are multiple teams (frontend, ci/cd, etc) that could use your help so please reach out! + +### Translation + +Paperless-ngx is available in many languages that are coordinated on [Crowdin](https://crwd.in/paperless-ngx). If you want to help out by translating paperless-ngx into your language, please head over to https://crwd.in/paperless-ngx, and thank you! + +## Scanners & Software + +Paperless-ngx is compatible with many different scanners and scanning tools. A user-maintained list of scanners and other software is available on [the wiki](https://github.com/paperless-ngx/paperless-ngx/wiki/Scanner-&-Software-Recommendations). diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 735804560..000000000 --- a/docs/index.rst +++ /dev/null @@ -1,75 +0,0 @@ -********* -Paperless -********* - -Paperless is a simple Django application running in two parts: -a *Consumer* (the thing that does the indexing) and -the *Web server* (the part that lets you search & -download already-indexed documents). If you want to learn more about its -functions keep on reading after the installation section. - - -Why This Exists -=============== - -Paper is a nightmare. Environmental issues aside, there's no excuse for it in -the 21st century. It takes up space, collects dust, doesn't support any form -of a search feature, indexing is tedious, it's heavy and prone to damage & -loss. - -I wrote this to make "going paperless" easier. I do not have to worry about -finding stuff again. I feed documents right from the post box into the scanner -and then shred them. Perhaps you might find it useful too. - - -Paperless-ngx -============= - -Paperless-ngx is a document management system that transforms your physical -documents into a searchable online archive so you can keep, well, *less paper*. - -Paperless-ngx forked from paperless-ng to continue the great work and -distribute responsibility of supporting and advancing the project among a team -of people. - -NG stands for both Angular (the framework used for the -Frontend) and next-gen. Publishing this project under a different name also -avoids confusion between paperless and paperless-ngx. - -If you want to learn about what's different in paperless-ngx from Paperless, check out these -resources in the documentation: - -* :ref:`Some screenshots ` of the new UI are available. -* Read :ref:`this section ` if you want to - learn about how paperless automates all tagging using machine learning. -* Paperless now comes with a :ref:`proper email consumer ` - that's fully tested and production ready. -* Paperless creates searchable PDF/A documents from whatever you put into - the consumption directory. This means that you can select text in - image-only documents coming from your scanner. -* See :ref:`this note ` about GnuPG encryption in - paperless-ngx. -* Paperless is now integrated with a - :ref:`task processing queue ` that tells you - at a glance when and why something is not working. -* The :doc:`changelog ` contains a detailed list of all changes - in paperless-ngx. - -Contents -======== - -.. toctree:: - :maxdepth: 1 - - setup - usage_overview - advanced_usage - administration - configuration - api - faq - troubleshooting - extending - scanners - screenshots - changelog diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index d911401cb..000000000 --- a/docs/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -myst-parser==0.18.1 diff --git a/docs/scanners.rst b/docs/scanners.rst deleted file mode 100644 index 68b0b335f..000000000 --- a/docs/scanners.rst +++ /dev/null @@ -1,8 +0,0 @@ - -.. _scanners: - -******************* -Scanners & Software -******************* - -Paperless-ngx is compatible with many different scanners and scanning tools. A user-maintained list of scanners and other software is available on `the wiki `_. diff --git a/docs/screenshots.rst b/docs/screenshots.rst deleted file mode 100644 index 1815575f1..000000000 --- a/docs/screenshots.rst +++ /dev/null @@ -1,63 +0,0 @@ -.. _screenshots: - -*********** -Screenshots -*********** - -This is what Paperless-ngx looks like. - -The dashboard shows customizable views on your document and allows document uploads: - -.. image:: _static/screenshots/dashboard.png - :target: _static/screenshots/dashboard.png - -The document list provides three different styles to scroll through your documents: - -.. image:: _static/screenshots/documents-table.png - :target: _static/screenshots/documents-table.png -.. image:: _static/screenshots/documents-smallcards.png - :target: _static/screenshots/documents-smallcards.png -.. image:: _static/screenshots/documents-largecards.png - :target: _static/screenshots/documents-largecards.png - -Paperless-ngx also supports "dark mode": - -.. image:: _static/screenshots/documents-smallcards-dark.png - :target: _static/screenshots/documents-smallcards-dark.png - -Extensive filtering mechanisms: - -.. image:: _static/screenshots/documents-filter.png - :target: _static/screenshots/documents-filter.png - -Bulk editing of document tags, correspondents, etc.: - -.. image:: _static/screenshots/bulk-edit.png - :target: _static/screenshots/bulk-edit.png - -Side-by-side editing of documents: - -.. image:: _static/screenshots/editing.png - :target: _static/screenshots/editing.png - -Tag editing. This looks about the same for correspondents and document types. - -.. image:: _static/screenshots/new-tag.png - :target: _static/screenshots/new-tag.png - -Searching provides auto complete and highlights the results. - -.. image:: _static/screenshots/search-preview.png - :target: _static/screenshots/search-preview.png -.. image:: _static/screenshots/search-results.png - :target: _static/screenshots/search-results.png - -Fancy mail filters! - -.. image:: _static/screenshots/mail-rules-edited.png - :target: _static/screenshots/mail-rules-edited.png - -Mobile devices are supported. - -.. image:: _static/screenshots/mobile.png - :target: _static/screenshots/mobile.png diff --git a/docs/setup.md b/docs/setup.md new file mode 100644 index 000000000..5ba453ab6 --- /dev/null +++ b/docs/setup.md @@ -0,0 +1,856 @@ +## Installation + +You can go multiple routes to setup and run Paperless: + +- [Use the easy install docker script](/setup#docker_script) +- [Pull the image from Docker Hub](/setup#docker_hub) +- [Build the Docker image yourself](/setup#docker_build) +- [Install Paperless directly on your system manually (bare metal)](/setup#bare_metal) + +The Docker routes are quick & easy. These are the recommended routes. +This configures all the stuff from the above automatically so that it +just works and uses sensible defaults for all configuration options. +Here you find a cheat-sheet for docker beginners: [CLI +Basics](https://www.sehn.tech/refs/devops-with-docker/) + +The bare metal route is complicated to setup but makes it easier should +you want to contribute some code back. You need to configure and run the +above mentioned components yourself. + +### Docker using the Installation Script {#docker_script} + +Paperless provides an interactive installation script. This script will +ask you for a couple configuration options, download and create the +necessary configuration files, pull the docker image, start paperless +and create your user account. This script essentially performs all the +steps described in [Docker setup](#docker_hub) automatically. + +1. Make sure that docker and docker-compose are installed. + +2. Download and run the installation script: + + ```shell-session + $ bash -c "$(curl -L https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)" + ``` + +### From GHCR / Docker Hub {#docker_hub} + +1. Login with your user and create a folder in your home-directory to have a place for your + configuration files and consumption directory. + + ```shell-session + $ mkdir -v ~/paperless-ngx + ``` + +2. Go to the [/docker/compose directory on the project + page](https://github.com/paperless-ngx/paperless-ngx/tree/master/docker/compose) + and download one of the `docker-compose.*.yml` files, + depending on which database backend you want to use. Rename this + file to `docker-compose.*.yml`. If you want to enable + optional support for Office documents, download a file with + `-tika` in the file name. Download the + `docker-compose.env` file and the `.env` file as well and store them + in the same directory. + + !!! tip + + For new installations, it is recommended to use PostgreSQL as the + database backend. + +3. Install [Docker](https://www.docker.com/) and + [docker-compose](https://docs.docker.com/compose/install/). + + !!! warning + + If you want to use the included `docker-compose.*.yml` file, you + need to have at least Docker version **17.09.0** and docker-compose + version **1.17.0**. To check do: `docker-compose -v` or + `docker -v` + + See the [Docker installation guide](https://docs.docker.com/engine/install/) on how to install the current + version of Docker for your operating system or Linux distribution of + choice. To get the latest version of docker-compose, follow the + [docker-compose installation guide](https://docs.docker.com/compose/install/linux/) if your package repository + doesn't include it. + +4. Modify `docker-compose.yml` to your preferences. You may want to + change the path to the consumption directory. Find the line that + specifies where to mount the consumption directory: + + ```yaml + - ./consume:/usr/src/paperless/consume + ``` + + Replace the part BEFORE the colon with a local directory of your + choice: + + ```yaml + - /home/jonaswinkler/paperless-inbox:/usr/src/paperless/consume + ``` + + Don't change the part after the colon or paperless wont find your + documents. + + You may also need to change the default port that the webserver will + use from the default (8000): + + ```yaml + ports: + - 8000:8000 + ``` + + Replace the part BEFORE the colon with a port of your choice: + + ```yaml + ports: + - 8010:8000 + ``` + + Don't change the part after the colon or edit other lines that + refer to port 8000. Modifying the part before the colon will map + requests on another port to the webserver running on the default + port. + + **Rootless** + + If you want to run Paperless as a rootless container, you will need + to do the following in your `docker-compose.yml`: + + - set the `user` running the container to map to the `paperless` + user in the container. This value (`user_id` below), should be + the same id that `USERMAP_UID` and `USERMAP_GID` are set to in + the next step. See `USERMAP_UID` and `USERMAP_GID` + [here](/configuration#docker). + + Your entry for Paperless should contain something like: + + > ``` + > webserver: + > image: ghcr.io/paperless-ngx/paperless-ngx:latest + > user: + > ``` + +5. Modify `docker-compose.env`, following the comments in the file. The + most important change is to set `USERMAP_UID` and `USERMAP_GID` to + the uid and gid of your user on the host system. Use `id -u` and + `id -g` to get these. + + This ensures that both the docker container and you on the host + machine have write access to the consumption directory. If your UID + and GID on the host system is 1000 (the default for the first normal + user on most systems), it will work out of the box without any + modifications. `id "username"` to check. + + !!! note + + You can copy any setting from the file `paperless.conf.example` and + paste it here. Have a look at [configuration](/configuration] to see what's available. + + !!! note + + You can utilize Docker secrets for some configuration settings by + appending `_FILE` to some configuration values. This is + supported currently only by: + + - PAPERLESS_DBUSER + - PAPERLESS_DBPASS + - PAPERLESS_SECRET_KEY + - PAPERLESS_AUTO_LOGIN_USERNAME + - PAPERLESS_ADMIN_USER + - PAPERLESS_ADMIN_MAIL + - PAPERLESS_ADMIN_PASSWORD + + !!! warning + + Some file systems such as NFS network shares don't support file + system notifications with `inotify`. When storing the consumption + directory on such a file system, paperless will not pick up new + files with the default configuration. You will need to use + `PAPERLESS_CONSUMER_POLLING`, which will disable inotify. See + [here](/configuration#polling). + +6. Run `docker-compose pull`, followed by `docker-compose up -d`. This + will pull the image, create and start the necessary containers. + +7. To be able to login, you will need a super user. To create it, + execute the following command: + + ```shell-session + $ docker-compose run --rm webserver createsuperuser + ``` + + This will prompt you to set a username, an optional e-mail address + and finally a password (at least 8 characters). + +8. The default `docker-compose.yml` exports the webserver on your local + port + + 8000\. If you did not change this, you should now be able to visit + your Paperless instance at `http://127.0.0.1:8000` or your servers + IP-Address:8000. Use the login credentials you have created with the + previous step. + +### Build the Docker image yourself {#docker_build} + +1. Clone the entire repository of paperless: + + ```shell-session + git clone https://github.com/paperless-ngx/paperless-ngx + ``` + + The master branch always reflects the latest stable version. + +2. Copy one of the `docker/compose/docker-compose.*.yml` to + `docker-compose.yml` in the root folder, depending on which database + backend you want to use. Copy `docker-compose.env` into the project + root as well. + +3. In the `docker-compose.yml` file, find the line that instructs + docker-compose to pull the paperless image from Docker Hub: + + ```yaml + webserver: + image: ghcr.io/paperless-ngx/paperless-ngx:latest + ``` + + and replace it with a line that instructs docker-compose to build + the image from the current working directory instead: + + ```yaml + webserver: + build: + context: . + args: + QPDF_VERSION: x.y.x + PIKEPDF_VERSION: x.y.z + PSYCOPG2_VERSION: x.y.z + JBIG2ENC_VERSION: 0.29 + ``` + + !!! note + + You should match the build argument versions to the version for the + release you have checked out. These are pre-built images with + certain, more updated software. If you want to build these images + your self, that is possible, but beyond the scope of these steps. + +4. Follow steps 3 to 8 of [Docker Setup](setup#docker_hub) + role="ref"}. When asked to run `docker-compose pull` to pull the + image, do + + ```shell-session + $ docker-compose build + ``` + + instead to build the image. + +### Bare Metal Route {#bare_metal} + +Paperless runs on linux only. The following procedure has been tested on +a minimal installation of Debian/Buster, which is the current stable +release at the time of writing. Windows is not and will never be +supported. + +1. Install dependencies. Paperless requires the following packages. + + - `python3` 3.8, 3.9 + - `python3-pip` + - `python3-dev` + - `default-libmysqlclient-dev` for MariaDB + - `fonts-liberation` for generating thumbnails for plain text + files + - `imagemagick` >= 6 for PDF conversion + - `gnupg` for handling encrypted documents + - `libpq-dev` for PostgreSQL + - `libmagic-dev` for mime type detection + - `mariadb-client` for MariaDB compile time + - `mime-support` for mime type detection + - `libzbar0` for barcode detection + - `poppler-utils` for barcode detection + + Use this list for your preferred package management: + + ``` + python3 python3-pip python3-dev imagemagick fonts-liberation gnupg libpq-dev default-libmysqlclient-dev libmagic-dev mime-support libzbar0 poppler-utils + ``` + + These dependencies are required for OCRmyPDF, which is used for text + recognition. + + - `unpaper` + - `ghostscript` + - `icc-profiles-free` + - `qpdf` + - `liblept5` + - `libxml2` + - `pngquant` (suggested for certain PDF image optimizations) + - `zlib1g` + - `tesseract-ocr` >= 4.0.0 for OCR + - `tesseract-ocr` language packs (`tesseract-ocr-eng`, + `tesseract-ocr-deu`, etc) + + Use this list for your preferred package management: + + ``` + unpaper ghostscript icc-profiles-free qpdf liblept5 libxml2 pngquant zlib1g tesseract-ocr + ``` + + On Raspberry Pi, these libraries are required as well: + + - `libatlas-base-dev` + - `libxslt1-dev` + + You will also need `build-essential`, `python3-setuptools` and + `python3-wheel` for installing some of the python dependencies. + +2. Install `redis` >= 6.0 and configure it to start automatically. + +3. Optional. Install `postgresql` and configure a database, user and + password for paperless. If you do not wish to use PostgreSQL, + MariaDB and SQLite are available as well. + + !!! note + + On bare-metal installations using SQLite, ensure the [JSON1 + extension](https://code.djangoproject.com/wiki/JSON1Extension) is + enabled. This is usually the case, but not always. + +4. Get the release archive from + . If you + clone the git repo as it is, you also have to compile the front end + by yourself. Extract the archive to a place from where you wish to + execute it, such as `/opt/paperless`. + +5. Configure paperless. See [configuration](configuration) for details. + Edit the included `paperless.conf` and adjust the settings to your + needs. Required settings for getting + paperless running are: + + - `PAPERLESS_REDIS` should point to your redis server, such as + . + - `PAPERLESS_DBENGINE` optional, and should be one of [postgres, + mariadb, or sqlite]{.title-ref} + - `PAPERLESS_DBHOST` should be the hostname on which your + PostgreSQL server is running. Do not configure this to use + SQLite instead. Also configure port, database name, user and + password as necessary. + - `PAPERLESS_CONSUMPTION_DIR` should point to a folder which + paperless should watch for documents. You might want to have + this somewhere else. Likewise, `PAPERLESS_DATA_DIR` and + `PAPERLESS_MEDIA_ROOT` define where paperless stores its data. + If you like, you can point both to the same directory. + - `PAPERLESS_SECRET_KEY` should be a random sequence of + characters. It's used for authentication. Failure to do so + allows third parties to forge authentication credentials. + - `PAPERLESS_URL` if you are behind a reverse proxy. This should + point to your domain. Please see + [configuration](configuration) for more + information. + + Many more adjustments can be made to paperless, especially the OCR + part. The following options are recommended for everyone: + + - Set `PAPERLESS_OCR_LANGUAGE` to the language most of your + documents are written in. + - Set `PAPERLESS_TIME_ZONE` to your local time zone. + +6. Create a system user under which you wish to run paperless. + + ```shell-session + adduser paperless --system --home /opt/paperless --group + ``` + +7. Ensure that these directories exist and that the paperless user has + write permissions to the following directories: + + - `/opt/paperless/media` + - `/opt/paperless/data` + - `/opt/paperless/consume` + + Adjust as necessary if you configured different folders. + +8. Install python requirements from the `requirements.txt` file. It is + up to you if you wish to use a virtual environment or not. First you + should update your pip, so it gets the actual packages. + + ```shell-session + sudo -Hu paperless pip3 install --upgrade pip + ``` + + ```shell-session + sudo -Hu paperless pip3 install -r requirements.txt + ``` + + This will install all python dependencies in the home directory of + the new paperless user. + +9. Go to `/opt/paperless/src`, and execute the following commands: + + ```bash + \# This creates the database schema. + sudo -Hu paperless python3 manage.py migrate + + \# This creates your first paperless user + sudo -Hu paperless python3 manage.py createsuperuser + ``` + +10. Optional: Test that paperless is working by executing + + ```bash + \# This collects static files from paperless and django. + sudo -Hu paperless python3 manage.py runserver + ``` + + and pointing your browser to . + + !!! warning + + This is a development server which should not be used in production. + It is not audited for security and performance is inferior to + production ready web servers. + + !!! tip + + This will not start the consumer. Paperless does this in a separate + process. + +11. Setup systemd services to run paperless automatically. You may use + the service definition files included in the `scripts` folder as a + starting point. + + Paperless needs the `webserver` script to run the webserver, the + `consumer` script to watch the input folder, `taskqueue` for the + background workers used to handle things like document consumption + and the `scheduler` script to run tasks such as email checking at + certain times . + + !!! note + + The `socket` script enables `gunicorn` to run on port 80 without + root privileges. For this you need to uncomment the + `Require=paperless-webserver.socket` in the `webserver` script + and configure `gunicorn` to listen on port 80 (see + `paperless/gunicorn.conf.py`). + + You may need to adjust the path to the `gunicorn` executable. This + will be installed as part of the python dependencies, and is either + located in the `bin` folder of your virtual environment, or in + `~/.local/bin/` if no virtual environment is used. + + These services rely on redis and optionally the database server, but + don't need to be started in any particular order. The example files + depend on redis being started. If you use a database server, you + should add additional dependencies. + + !!! warning + + The included scripts run a `gunicorn` standalone server, which is + fine for running paperless. It does support SSL, however, the + documentation of GUnicorn states that you should use a proxy server + in front of gunicorn instead. + + For instructions on how to use nginx for that, + [see the instructions below](/setup#nginx). + +12. Optional: Install a samba server and make the consumption folder + available as a network share. + +13. Configure ImageMagick to allow processing of PDF documents. Most + distributions have this disabled by default, since PDF documents can + contain malware. If you don't do this, paperless will fall back to + ghostscript for certain steps such as thumbnail generation. + + Edit `/etc/ImageMagick-6/policy.xml` and adjust + + ``` + + ``` + + to + + ``` + + ``` + +14. Optional: Install the + [jbig2enc](https://ocrmypdf.readthedocs.io/en/latest/jbig2.html) + encoder. This will reduce the size of generated PDF documents. + You'll most likely need to compile this by yourself, because this + software has been patented until around 2017 and binary packages are + not available for most distributions. + +15. Optional: If using the NLTK machine learning processing (see + `PAPERLESS_ENABLE_NLTK` in [configuration](configuration#software_tweaks) for details), + download the NLTK data for the Snowball + Stemmer, Stopwords and Punkt tokenizer to your + `PAPERLESS_DATA_DIR/nltk`. Refer to the [NLTK + instructions](https://www.nltk.org/data.html) for details on how to + download the data. + +# Migrating to Paperless-ngx + +Migration is possible both from Paperless-ng or directly from the +'original' Paperless. + +## Migrating from Paperless-ng + +Paperless-ngx is meant to be a drop-in replacement for Paperless-ng and +thus upgrading should be trivial for most users, especially when using +docker. However, as with any major change, it is recommended to take a +full backup first. Once you are ready, simply change the docker image to +point to the new source. E.g. if using Docker Compose, edit +`docker-compose.yml` and change: + +``` +image: jonaswinkler/paperless-ng:latest +``` + +to + +``` +image: ghcr.io/paperless-ngx/paperless-ngx:latest +``` + +and then run `docker-compose up -d` which will pull the new image +recreate the container. That's it! + +Users who installed with the bare-metal route should also update their +Git clone to point to `https://github.com/paperless-ngx/paperless-ngx`, +e.g. using the command +`git remote set-url origin https://github.com/paperless-ngx/paperless-ngx` +and then pull the lastest version. + +## Migrating from Paperless + +At its core, paperless-ngx is still paperless and fully compatible. +However, some things have changed under the hood, so you need to adapt +your setup depending on how you installed paperless. + +This setup describes how to update an existing paperless Docker +installation. The important things to keep in mind are as follows: + +- Read the [changelog](/changelog) and + take note of breaking changes. +- You should decide if you want to stick with SQLite or want to + migrate your database to PostgreSQL. See [documentation](#sqlite_to_psql) + for details on + how to move your data from SQLite to PostgreSQL. Both work fine with + paperless. However, if you already have a database server running + for other services, you might as well use it for paperless as well. +- The task scheduler of paperless, which is used to execute periodic + tasks such as email checking and maintenance, requires a + [redis](https://redis.io/) message broker instance. The + docker-compose route takes care of that. +- The layout of the folder structure for your documents and data + remains the same, so you can just plug your old docker volumes into + paperless-ngx and expect it to find everything where it should be. + +Migration to paperless-ngx is then performed in a few simple steps: + +1. Stop paperless. + + ```bash + $ cd /path/to/current/paperless + $ docker-compose down + ``` + +2. Do a backup for two purposes: If something goes wrong, you still + have your data. Second, if you don't like paperless-ngx, you can + switch back to paperless. + +3. Download the latest release of paperless-ngx. You can either go with + the docker-compose files from + [here](https://github.com/paperless-ngx/paperless-ngx/tree/master/docker/compose) + or clone the repository to build the image yourself (see + [above](/setup#docker_build)). You can + either replace your current paperless folder or put paperless-ngx in + a different location. + + !!! warning + + Paperless-ngx includes a `.env` file. This will set the project name + for docker compose to `paperless`, which will also define the name + of the volumes by paperless-ngx. However, if you experience that + paperless-ngx is not using your old paperless volumes, verify the + names of your volumes with + + ``` shell-session + $ docker volume ls | grep _data + ``` + + and adjust the project name in the `.env` file so that it matches + the name of the volumes before the `_data` part. + +4. Download the `docker-compose.sqlite.yml` file to + `docker-compose.yml`. If you want to switch to PostgreSQL, do that + after you migrated your existing SQLite database. + +5. Adjust `docker-compose.yml` and `docker-compose.env` to your needs. + See [Docker setup](setup#docker_hub) details on + which edits are advised. + +6. [Update paperless.](/administration#updating) + +7. In order to find your existing documents with the new search + feature, you need to invoke a one-time operation that will create + the search index: + + ```shell-session + $ docker-compose run --rm webserver document_index reindex + ``` + + This will migrate your database and create the search index. After + that, paperless will take care of maintaining the index by itself. + +8. Start paperless-ngx. + + ```bash + $ docker-compose up -d + ``` + + This will run paperless in the background and automatically start it + on system boot. + +9. Paperless installed a permanent redirect to `admin/` in your + browser. This redirect is still in place and prevents access to the + new UI. Clear your browsing cache in order to fix this. + +10. Optionally, follow the instructions below to migrate your existing + data to PostgreSQL. + +## Migrating from LinuxServer.io Docker Image + +As with any upgrades and large changes, it is highly recommended to +create a backup before starting. This assumes the image was running +using Docker Compose, but the instructions are translatable to Docker +commands as well. + +1. Stop and remove the paperless container +2. If using an external database, stop the container +3. Update Redis configuration + a) If `REDIS_URL` is already set, change it to `PAPERLESS_REDIS` + and continue to step 4. + b) Otherwise, in the `docker-compose.yml` add a new service for + Redis, following [the example compose + files](https://github.com/paperless-ngx/paperless-ngx/tree/main/docker/compose) + c) Set the environment variable `PAPERLESS_REDIS` so it points to + the new Redis container +4. Update user mapping + a) If set, change the environment variable `PUID` to `USERMAP_UID` + b) If set, change the environment variable `PGID` to `USERMAP_GID` +5. Update configuration paths + a) Set the environment variable `PAPERLESS_DATA_DIR` to `/config` +6. Update media paths + a) Set the environment variable `PAPERLESS_MEDIA_ROOT` to + `/data/media` +7. Update timezone + a) Set the environment variable `PAPERLESS_TIME_ZONE` to the same + value as `TZ` +8. Modify the `image:` to point to + `ghcr.io/paperless-ngx/paperless-ngx:latest` or a specific version + if preferred. +9. Start the containers as before, using `docker-compose`. + +## Moving data from SQLite to PostgreSQL or MySQL/MariaDB {#sqlite_to_psql} + +Moving your data from SQLite to PostgreSQL or MySQL/MariaDB is done via +executing a series of django management commands as below. The commands +below use PostgreSQL, but are applicable to MySQL/MariaDB with the + +!!! warning + + Make sure that your SQLite database is migrated to the latest version. + Starting paperless will make sure that this is the case. If your try to + load data from an old database schema in SQLite into a newer database + schema in PostgreSQL, you will run into trouble. + +!!! warning + + On some database fields, PostgreSQL enforces predefined limits on + maximum length, whereas SQLite does not. The fields in question are the + title of documents (128 characters), names of document types, tags and + correspondents (128 characters), and filenames (1024 characters). If you + have data in these fields that surpasses these limits, migration to + PostgreSQL is not possible and will fail with an error. + +!!! warning + + MySQL is case insensitive by default, treating values like "Name" and + "NAME" as identical. See [MySQL caveats](advanced##mysql-caveats) for details. + +!!! warning + + MySQL also enforces limits on maximum lengths, but does so differently than + PostgreSQL. It may not be possible to migrate to MySQL due to this. + +1. Stop paperless, if it is running. + +2. Tell paperless to use PostgreSQL: + + a) With docker, copy the provided `docker-compose.postgres.yml` + file to `docker-compose.yml`. Remember to adjust the consumption + directory, if necessary. + b) Without docker, configure the database in your `paperless.conf` + file. See [configuration](configuration) for + details. + +3. Open a shell and initialize the database: + + a) With docker, run the following command to open a shell within + the paperless container: + + ``` shell-session + $ cd /path/to/paperless + $ docker-compose run --rm webserver /bin/bash + ``` + + This will launch the container and initialize the PostgreSQL + database. + + b) Without docker, remember to activate any virtual environment, + switch to the `src` directory and create the database schema: + + ``` shell-session + $ cd /path/to/paperless/src + $ python3 manage.py migrate + ``` + + This will not copy any data yet. + +4. Dump your data from SQLite: + + ```shell-session + $ python3 manage.py dumpdata --database=sqlite --exclude=contenttypes --exclude=auth.Permission > data.json + ``` + +5. Load your data into PostgreSQL: + + ```shell-session + $ python3 manage.py loaddata data.json + ``` + +6. If operating inside Docker, you may exit the shell now. + + ```shell-session + $ exit + ``` + +7. Start paperless. + +## Moving back to Paperless + +Lets say you migrated to Paperless-ngx and used it for a while, but +decided that you don't like it and want to move back (If you do, send +me a mail about what part you didn't like!), you can totally do that +with a few simple steps. + +Paperless-ngx modified the database schema slightly, however, these +changes can be reverted while keeping your current data, so that your +current data will be compatible with original Paperless. + +Execute this: + +```shell-session +$ cd /path/to/paperless +$ docker-compose run --rm webserver migrate documents 0023 +``` + +Or without docker: + +```shell-session +$ cd /path/to/paperless/src +$ python3 manage.py migrate documents 0023 +``` + +After that, you need to clear your cookies (Paperless-ngx comes with +updated dependencies that do cookie-processing differently) and probably +your cache as well. + +# Considerations for less powerful devices {#less_powerful_devices} + +Paperless runs on Raspberry Pi. However, some things are rather slow on +the Pi and configuring some options in paperless can help improve +performance immensely: + +- Stick with SQLite to save some resources. +- Consider setting `PAPERLESS_OCR_PAGES` to 1, so that paperless will + only OCR the first page of your documents. In most cases, this page + contains enough information to be able to find it. +- `PAPERLESS_TASK_WORKERS` and `PAPERLESS_THREADS_PER_WORKER` are + configured to use all cores. The Raspberry Pi models 3 and up have 4 + cores, meaning that paperless will use 2 workers and 2 threads per + worker. This may result in sluggish response times during + consumption, so you might want to lower these settings (example: 2 + workers and 1 thread to always have some computing power left for + other tasks). +- Keep `PAPERLESS_OCR_MODE` at its default value `skip` and consider + OCR'ing your documents before feeding them into paperless. Some + scanners are able to do this! You might want to even specify + `skip_noarchive` to skip archive file generation for already ocr'ed + documents entirely. +- If you want to perform OCR on the device, consider using + `PAPERLESS_OCR_CLEAN=none`. This will speed up OCR times and use + less memory at the expense of slightly worse OCR results. +- If using docker, consider setting `PAPERLESS_WEBSERVER_WORKERS` to + 1. This will save some memory. +- Consider setting `PAPERLESS_ENABLE_NLTK` to false, to disable the + more advanced language processing, which can take more memory and + processing time. + +For details, refer to [configuration](configuration). + +!!! note + + Updating the + [automatic matching algorithm](/advanced_usage#automatic_matching) takes quite a bit of time. However, the update mechanism + checks if your data has changed before doing the heavy lifting. If you + experience the algorithm taking too much cpu time, consider changing the + schedule in the admin interface to daily. You can also manually invoke + the task by changing the date and time of the next run to today/now. + + The actual matching of the algorithm is fast and works on Raspberry Pi + as well as on any other device. + +# Using nginx as a reverse proxy {#nginx} + +If you want to expose paperless to the internet, you should hide it +behind a reverse proxy with SSL enabled. + +In addition to the usual configuration for SSL, the following +configuration is required for paperless to operate: + +```nginx +http { + + # Adjust as required. This is the maximum size for file uploads. + # The default value 1M might be a little too small. + client_max_body_size 10M; + + server { + + location / { + + # Adjust host and port as required. + proxy_pass http://localhost:8000/; + + # These configuration options are required for WebSockets to work. + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + } + } +} +``` + +The `PAPERLESS_URL` configuration variable is also required when using a +reverse proxy. Please refer to the [hosting and security](configuration#hosting-and-security) docs. + +Also read +[this](https://channels.readthedocs.io/en/stable/deploying.html#nginx-supervisor-ubuntu), +towards the end of the section. diff --git a/docs/setup.rst b/docs/setup.rst deleted file mode 100644 index 15f16d193..000000000 --- a/docs/setup.rst +++ /dev/null @@ -1,846 +0,0 @@ - -***** -Setup -***** - -Overview of Paperless-ngx -######################### - -Compared to paperless, paperless-ngx works a little different under the hood and has -more moving parts that work together. While this increases the complexity of -the system, it also brings many benefits. - -Paperless consists of the following components: - -* **The webserver:** This is pretty much the same as in paperless. It serves - the administration pages, the API, and the new frontend. This is the main - tool you'll be using to interact with paperless. You may start the webserver - with - - .. code:: shell-session - - $ cd /path/to/paperless/src/ - $ gunicorn -c ../gunicorn.conf.py paperless.wsgi - - or by any other means such as Apache ``mod_wsgi``. - -* **The consumer:** This is what watches your consumption folder for documents. - However, the consumer itself does not really consume your documents. - Now it notifies a task processor that a new file is ready for consumption. - I suppose it should be named differently. - This was also used to check your emails, but that's now done elsewhere as well. - - Start the consumer with the management command ``document_consumer``: - - .. code:: shell-session - - $ cd /path/to/paperless/src/ - $ python3 manage.py document_consumer - - .. _setup-task_processor: - -* **The task processor:** Paperless relies on `Celery - Distributed Task Queue `_ - for doing most of the heavy lifting. This is a task queue that accepts tasks from - multiple sources and processes these in parallel. It also comes with a scheduler that executes - certain commands periodically. - - This task processor is responsible for: - - * Consuming documents. When the consumer finds new documents, it notifies the task processor to - start a consumption task. - * The task processor also performs the consumption of any documents you upload through - the web interface. - * Consuming emails. It periodically checks your configured accounts for new emails and - notifies the task processor to consume the attachment of an email. - * Maintaining the search index and the automatic matching algorithm. These are things that paperless - needs to do from time to time in order to operate properly. - - This allows paperless to process multiple documents from your consumption folder in parallel! On - a modern multi core system, this makes the consumption process with full OCR blazingly fast. - - The task processor comes with a built-in admin interface that you can use to check whenever any of the - tasks fail and inspect the errors (i.e., wrong email credentials, errors during consuming a specific - file, etc). - -* A `redis `_ message broker: This is a really lightweight service that is responsible - for getting the tasks from the webserver and the consumer to the task scheduler. These run in a different - process (maybe even on different machines!), and therefore, this is necessary. - -* Optional: A database server. Paperless supports PostgreSQL, MariaDB and SQLite for storing its data. - - -Installation -############ - -You can go multiple routes to setup and run Paperless: - -* :ref:`Use the easy install docker script ` -* :ref:`Pull the image from Docker Hub ` -* :ref:`Build the Docker image yourself ` -* :ref:`Install Paperless directly on your system manually (bare metal) ` - -The Docker routes are quick & easy. These are the recommended routes. This configures all the stuff -from the above automatically so that it just works and uses sensible defaults for all configuration options. -Here you find a cheat-sheet for docker beginners: `CLI Basics `_ - -The bare metal route is complicated to setup but makes it easier -should you want to contribute some code back. You need to configure and -run the above mentioned components yourself. - -.. _CLI Basics: https://www.sehn.tech/refs/devops-with-docker/ - -.. _setup-docker_script: - -Install Paperless from Docker Hub using the installation script -=============================================================== - -Paperless provides an interactive installation script. This script will ask you -for a couple configuration options, download and create the necessary configuration files, pull the docker image, start paperless and create your user account. This script essentially -performs all the steps described in :ref:`setup-docker_hub` automatically. - -1. Make sure that docker and docker-compose are installed. -2. Download and run the installation script: - - .. code:: shell-session - - $ bash -c "$(curl -L https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)" - -.. _setup-docker_hub: - -Install Paperless from Docker Hub -================================= - -1. Login with your user and create a folder in your home-directory `mkdir -v ~/paperless-ngx` to have a place for your configuration files and consumption directory. - -2. Go to the `/docker/compose directory on the project page `_ - and download one of the `docker-compose.*.yml` files, depending on which database backend you - want to use. Rename this file to `docker-compose.yml`. - If you want to enable optional support for Office documents, download a file with `-tika` in the file name. - Download the ``docker-compose.env`` file and the ``.env`` file as well and store them - in the same directory. - - .. hint:: - - For new installations, it is recommended to use PostgreSQL as the database - backend. - -3. Install `Docker`_ and `docker-compose`_. - - .. caution:: - - If you want to use the included ``docker-compose.*.yml`` file, you - need to have at least Docker version **17.09.0** and docker-compose - version **1.17.0**. - To check do: `docker-compose -v` or `docker -v` - - See the `Docker installation guide`_ on how to install the current - version of Docker for your operating system or Linux distribution of - choice. To get the latest version of docker-compose, follow the - `docker-compose installation guide`_ if your package repository doesn't - include it. - - .. _Docker installation guide: https://docs.docker.com/engine/installation/ - .. _docker-compose installation guide: https://docs.docker.com/compose/install/ - -4. Modify ``docker-compose.yml`` to your preferences. You may want to change the path - to the consumption directory. Find the line that specifies where - to mount the consumption directory: - - .. code:: - - - ./consume:/usr/src/paperless/consume - - Replace the part BEFORE the colon with a local directory of your choice: - - .. code:: - - - /home/jonaswinkler/paperless-inbox:/usr/src/paperless/consume - - Don't change the part after the colon or paperless wont find your documents. - - You may also need to change the default port that the webserver will use - from the default (8000): - - .. code:: - - ports: - - 8000:8000 - - Replace the part BEFORE the colon with a port of your choice: - - .. code:: - - ports: - - 8010:8000 - - Don't change the part after the colon or edit other lines that refer to - port 8000. Modifying the part before the colon will map requests on another - port to the webserver running on the default port. - - **Rootless** - - If you want to run Paperless as a rootless container, you will need to do the - following in your ``docker-compose.yml``: - - - set the ``user`` running the container to map to the ``paperless`` user in the - container. - This value (``user_id`` below), should be the same id that ``USERMAP_UID`` and - ``USERMAP_GID`` are set to in the next step. - See ``USERMAP_UID`` and ``USERMAP_GID`` :ref:`here `. - - Your entry for Paperless should contain something like: - - .. code:: - - webserver: - image: ghcr.io/paperless-ngx/paperless-ngx:latest - user: - -5. Modify ``docker-compose.env``, following the comments in the file. The - most important change is to set ``USERMAP_UID`` and ``USERMAP_GID`` - to the uid and gid of your user on the host system. Use ``id -u`` and - ``id -g`` to get these. - - This ensures that - both the docker container and you on the host machine have write access - to the consumption directory. If your UID and GID on the host system is - 1000 (the default for the first normal user on most systems), it will - work out of the box without any modifications. `id "username"` to check. - - .. note:: - - You can copy any setting from the file ``paperless.conf.example`` and paste it here. - Have a look at :ref:`configuration` to see what's available. - - .. note:: - - You can utilize Docker secrets for some configuration settings by - appending `_FILE` to some configuration values. This is supported currently - only by: - - * PAPERLESS_DBUSER - * PAPERLESS_DBPASS - * PAPERLESS_SECRET_KEY - * PAPERLESS_AUTO_LOGIN_USERNAME - * PAPERLESS_ADMIN_USER - * PAPERLESS_ADMIN_MAIL - * PAPERLESS_ADMIN_PASSWORD - - .. caution:: - - Some file systems such as NFS network shares don't support file system - notifications with ``inotify``. When storing the consumption directory - on such a file system, paperless will not pick up new files - with the default configuration. You will need to use ``PAPERLESS_CONSUMER_POLLING``, - which will disable inotify. See :ref:`here `. - -6. Run ``docker-compose pull``, followed by ``docker-compose up -d``. - This will pull the image, create and start the necessary containers. - -7. To be able to login, you will need a super user. To create it, execute the - following command: - - .. code-block:: shell-session - - $ docker-compose run --rm webserver createsuperuser - - This will prompt you to set a username, an optional e-mail address and - finally a password (at least 8 characters). - -8. The default ``docker-compose.yml`` exports the webserver on your local port - 8000. If you did not change this, you should now be able to visit your - Paperless instance at ``http://127.0.0.1:8000`` or your servers IP-Address:8000. - Use the login credentials you have created with the previous step. - -.. _Docker: https://www.docker.com/ -.. _docker-compose: https://docs.docker.com/compose/install/ - -.. _setup-docker_build: - -Build the Docker image yourself -=============================== - -1. Clone the entire repository of paperless: - - .. code:: shell-session - - git clone https://github.com/paperless-ngx/paperless-ngx - - The master branch always reflects the latest stable version. - -2. Copy one of the ``docker/compose/docker-compose.*.yml`` to ``docker-compose.yml`` in the root folder, - depending on which database backend you want to use. Copy - ``docker-compose.env`` into the project root as well. - -3. In the ``docker-compose.yml`` file, find the line that instructs docker-compose to pull the paperless image from Docker Hub: - - .. code:: yaml - - webserver: - image: ghcr.io/paperless-ngx/paperless-ngx:latest - - and replace it with a line that instructs docker-compose to build the image from the current working directory instead: - - .. code:: yaml - - webserver: - build: - context: . - args: - QPDF_VERSION: x.y.x - PIKEPDF_VERSION: x.y.z - PSYCOPG2_VERSION: x.y.z - JBIG2ENC_VERSION: 0.29 - - .. note:: - - You should match the build argument versions to the version for the release you have - checked out. These are pre-built images with certain, more updated software. - If you want to build these images your self, that is possible, but beyond - the scope of these steps. - -4. Follow steps 3 to 8 of :ref:`setup-docker_hub`. When asked to run - ``docker-compose pull`` to pull the image, do - - .. code:: shell-session - - $ docker-compose build - - instead to build the image. - -.. _setup-bare_metal: - -Bare Metal Route -================ - -Paperless runs on linux only. The following procedure has been tested on a minimal -installation of Debian/Buster, which is the current stable release at the time of -writing. Windows is not and will never be supported. - -1. Install dependencies. Paperless requires the following packages. - - * ``python3`` 3.8, 3.9 - * ``python3-pip`` - * ``python3-dev`` - - * ``default-libmysqlclient-dev`` for MariaDB - * ``fonts-liberation`` for generating thumbnails for plain text files - * ``imagemagick`` >= 6 for PDF conversion - * ``gnupg`` for handling encrypted documents - * ``libpq-dev`` for PostgreSQL - * ``libmagic-dev`` for mime type detection - * ``mariadb-client`` for MariaDB compile time - * ``mime-support`` for mime type detection - * ``libzbar0`` for barcode detection - * ``poppler-utils`` for barcode detection - - Use this list for your preferred package management: - - .. code:: - - python3 python3-pip python3-dev imagemagick fonts-liberation gnupg libpq-dev default-libmysqlclient-dev libmagic-dev mime-support libzbar0 poppler-utils - - These dependencies are required for OCRmyPDF, which is used for text recognition. - - * ``unpaper`` - * ``ghostscript`` - * ``icc-profiles-free`` - * ``qpdf`` - * ``liblept5`` - * ``libxml2`` - * ``pngquant`` (suggested for certain PDF image optimizations) - * ``zlib1g`` - * ``tesseract-ocr`` >= 4.0.0 for OCR - * ``tesseract-ocr`` language packs (``tesseract-ocr-eng``, ``tesseract-ocr-deu``, etc) - - Use this list for your preferred package management: - - .. code:: - - unpaper ghostscript icc-profiles-free qpdf liblept5 libxml2 pngquant zlib1g tesseract-ocr - - On Raspberry Pi, these libraries are required as well: - - * ``libatlas-base-dev`` - * ``libxslt1-dev`` - - You will also need ``build-essential``, ``python3-setuptools`` and ``python3-wheel`` - for installing some of the python dependencies. - -2. Install ``redis`` >= 6.0 and configure it to start automatically. - -3. Optional. Install ``postgresql`` and configure a database, user and password for paperless. If you do not wish - to use PostgreSQL, MariaDB and SQLite are available as well. - - .. note:: - - On bare-metal installations using SQLite, ensure the - `JSON1 extension `_ is enabled. This is - usually the case, but not always. - -4. Get the release archive from ``_. - If you clone the git repo as it is, you also have to compile the front end by yourself. - Extract the archive to a place from where you wish to execute it, such as ``/opt/paperless``. - -5. Configure paperless. See :ref:`configuration` for details. Edit the included ``paperless.conf`` and adjust the - settings to your needs. Required settings for getting paperless running are: - - * ``PAPERLESS_REDIS`` should point to your redis server, such as redis://localhost:6379. - * ``PAPERLESS_DBENGINE`` optional, and should be one of `postgres, mariadb, or sqlite` - * ``PAPERLESS_DBHOST`` should be the hostname on which your PostgreSQL server is running. Do not configure this - to use SQLite instead. Also configure port, database name, user and password as necessary. - * ``PAPERLESS_CONSUMPTION_DIR`` should point to a folder which paperless should watch for documents. You might - want to have this somewhere else. Likewise, ``PAPERLESS_DATA_DIR`` and ``PAPERLESS_MEDIA_ROOT`` define where - paperless stores its data. If you like, you can point both to the same directory. - * ``PAPERLESS_SECRET_KEY`` should be a random sequence of characters. It's used for authentication. Failure - to do so allows third parties to forge authentication credentials. - * ``PAPERLESS_URL`` if you are behind a reverse proxy. This should point to your domain. Please see - :ref:`configuration` for more information. - - Many more adjustments can be made to paperless, especially the OCR part. The following options are recommended - for everyone: - - * Set ``PAPERLESS_OCR_LANGUAGE`` to the language most of your documents are written in. - * Set ``PAPERLESS_TIME_ZONE`` to your local time zone. - -6. Create a system user under which you wish to run paperless. - - .. code:: shell-session - - adduser paperless --system --home /opt/paperless --group - -7. Ensure that these directories exist - and that the paperless user has write permissions to the following directories: - - * ``/opt/paperless/media`` - * ``/opt/paperless/data`` - * ``/opt/paperless/consume`` - - Adjust as necessary if you configured different folders. - -8. Install python requirements from the ``requirements.txt`` file. - It is up to you if you wish to use a virtual environment or not. First you should update your pip, so it gets the actual packages. - - .. code:: shell-session - - sudo -Hu paperless pip3 install --upgrade pip - - .. code:: shell-session - - sudo -Hu paperless pip3 install -r requirements.txt - - This will install all python dependencies in the home directory of - the new paperless user. - -9. Go to ``/opt/paperless/src``, and execute the following commands: - - .. code:: bash - - # This creates the database schema. - sudo -Hu paperless python3 manage.py migrate - - # This creates your first paperless user - sudo -Hu paperless python3 manage.py createsuperuser - -10. Optional: Test that paperless is working by executing - - .. code:: bash - - # This collects static files from paperless and django. - sudo -Hu paperless python3 manage.py runserver - - and pointing your browser to http://localhost:8000/. - - .. warning:: - - This is a development server which should not be used in - production. It is not audited for security and performance - is inferior to production ready web servers. - - .. hint:: - - This will not start the consumer. Paperless does this in a - separate process. - -11. Setup systemd services to run paperless automatically. You may - use the service definition files included in the ``scripts`` folder - as a starting point. - - Paperless needs the ``webserver`` script to run the webserver, the - ``consumer`` script to watch the input folder, ``taskqueue`` for the background workers - used to handle things like document consumption and the ``scheduler`` script to run tasks such as - email checking at certain times . - - The ``socket`` script enables ``gunicorn`` to run on port 80 without - root privileges. For this you need to uncomment the ``Require=paperless-webserver.socket`` - in the ``webserver`` script and configure ``gunicorn`` to listen on port 80 (see ``paperless/gunicorn.conf.py``). - - You may need to adjust the path to the ``gunicorn`` executable. This - will be installed as part of the python dependencies, and is either located - in the ``bin`` folder of your virtual environment, or in ``~/.local/bin/`` if - no virtual environment is used. - - These services rely on redis and optionally the database server, but - don't need to be started in any particular order. The example files - depend on redis being started. If you use a database server, you should - add additional dependencies. - - .. caution:: - - The included scripts run a ``gunicorn`` standalone server, - which is fine for running paperless. It does support SSL, - however, the documentation of GUnicorn states that you should - use a proxy server in front of gunicorn instead. - - For instructions on how to use nginx for that, - :ref:`see the instructions below `. - -12. Optional: Install a samba server and make the consumption folder - available as a network share. - -13. Configure ImageMagick to allow processing of PDF documents. Most distributions have - this disabled by default, since PDF documents can contain malware. If - you don't do this, paperless will fall back to ghostscript for certain steps - such as thumbnail generation. - - Edit ``/etc/ImageMagick-6/policy.xml`` and adjust - - .. code:: - - - - to - - .. code:: - - - -14. Optional: Install the `jbig2enc `_ - encoder. This will reduce the size of generated PDF documents. You'll most likely need - to compile this by yourself, because this software has been patented until around 2017 and - binary packages are not available for most distributions. - -15. Optional: If using the NLTK machine learning processing (see ``PAPERLESS_ENABLE_NLTK`` in - :ref:`configuration` for details), download the NLTK data for the Snowball Stemmer, Stopwords - and Punkt tokenizer to your ``PAPERLESS_DATA_DIR/nltk``. Refer to - the `NLTK instructions `_ for details on how to - download the data. - - -Migrating to Paperless-ngx -########################## - -Migration is possible both from Paperless-ng or directly from the 'original' Paperless. - -Migrating from Paperless-ng -=========================== - -Paperless-ngx is meant to be a drop-in replacement for Paperless-ng and thus upgrading should be -trivial for most users, especially when using docker. However, as with any major change, it is -recommended to take a full backup first. Once you are ready, simply change the docker image to -point to the new source. E.g. if using Docker Compose, edit ``docker-compose.yml`` and change: - -.. code:: - - image: jonaswinkler/paperless-ng:latest - -to - -.. code:: - - image: ghcr.io/paperless-ngx/paperless-ngx:latest - -and then run ``docker-compose up -d`` which will pull the new image recreate the container. -That's it! - -Users who installed with the bare-metal route should also update their Git clone to point to -``https://github.com/paperless-ngx/paperless-ngx``, e.g. using the command -``git remote set-url origin https://github.com/paperless-ngx/paperless-ngx`` and then pull the -lastest version. - -Migrating from Paperless -======================== - -At its core, paperless-ngx is still paperless and fully compatible. However, some -things have changed under the hood, so you need to adapt your setup depending on -how you installed paperless. - -This setup describes how to update an existing paperless Docker installation. -The important things to keep in mind are as follows: - -* Read the :doc:`changelog ` and take note of breaking changes. -* You should decide if you want to stick with SQLite or want to migrate your database - to PostgreSQL. See :ref:`setup-sqlite_to_psql` for details on how to move your data from - SQLite to PostgreSQL. Both work fine with paperless. However, if you already have a - database server running for other services, you might as well use it for paperless as well. -* The task scheduler of paperless, which is used to execute periodic tasks - such as email checking and maintenance, requires a `redis`_ message broker - instance. The docker-compose route takes care of that. -* The layout of the folder structure for your documents and data remains the - same, so you can just plug your old docker volumes into paperless-ngx and - expect it to find everything where it should be. - -Migration to paperless-ngx is then performed in a few simple steps: - -1. Stop paperless. - - .. code:: bash - - $ cd /path/to/current/paperless - $ docker-compose down - -2. Do a backup for two purposes: If something goes wrong, you still have your - data. Second, if you don't like paperless-ngx, you can switch back to - paperless. - -3. Download the latest release of paperless-ngx. You can either go with the - docker-compose files from `here `__ - or clone the repository to build the image yourself (see :ref:`above `). - You can either replace your current paperless folder or put paperless-ngx - in a different location. - - .. caution:: - - Paperless-ngx includes a ``.env`` file. This will set the - project name for docker compose to ``paperless``, which will also define the name - of the volumes by paperless-ngx. However, if you experience that paperless-ngx - is not using your old paperless volumes, verify the names of your volumes with - - .. code:: shell-session - - $ docker volume ls | grep _data - - and adjust the project name in the ``.env`` file so that it matches the name - of the volumes before the ``_data`` part. - - -4. Download the ``docker-compose.sqlite.yml`` file to ``docker-compose.yml``. - If you want to switch to PostgreSQL, do that after you migrated your existing - SQLite database. - -5. Adjust ``docker-compose.yml`` and ``docker-compose.env`` to your needs. - See :ref:`setup-docker_hub` for details on which edits are advised. - -6. :ref:`Update paperless. ` - -7. In order to find your existing documents with the new search feature, you need - to invoke a one-time operation that will create the search index: - - .. code:: shell-session - - $ docker-compose run --rm webserver document_index reindex - - This will migrate your database and create the search index. After that, - paperless will take care of maintaining the index by itself. - -8. Start paperless-ngx. - - .. code:: bash - - $ docker-compose up -d - - This will run paperless in the background and automatically start it on system boot. - -9. Paperless installed a permanent redirect to ``admin/`` in your browser. This - redirect is still in place and prevents access to the new UI. Clear your - browsing cache in order to fix this. - -10. Optionally, follow the instructions below to migrate your existing data to PostgreSQL. - - -.. _setup-sqlite_to_psql: - -Moving data from SQLite to PostgreSQL -===================================== - -Moving your data from SQLite to PostgreSQL is done via executing a series of django -management commands as below. - -.. caution:: - - Make sure that your SQLite database is migrated to the latest version. - Starting paperless will make sure that this is the case. If your try to - load data from an old database schema in SQLite into a newer database - schema in PostgreSQL, you will run into trouble. - -.. warning:: - - On some database fields, PostgreSQL enforces predefined limits on maximum - length, whereas SQLite does not. The fields in question are the title of documents - (128 characters), names of document types, tags and correspondents (128 characters), - and filenames (1024 characters). If you have data in these fields that surpasses these - limits, migration to PostgreSQL is not possible and will fail with an error. - - -1. Stop paperless, if it is running. -2. Tell paperless to use PostgreSQL: - - a) With docker, copy the provided ``docker-compose.postgres.yml`` file to - ``docker-compose.yml``. Remember to adjust the consumption directory, - if necessary. - b) Without docker, configure the database in your ``paperless.conf`` file. - See :ref:`configuration` for details. - -3. Open a shell and initialize the database: - - a) With docker, run the following command to open a shell within the paperless - container: - - .. code:: shell-session - - $ cd /path/to/paperless - $ docker-compose run --rm webserver /bin/bash - - This will launch the container and initialize the PostgreSQL database. - - b) Without docker, remember to activate any virtual environment, switch to - the ``src`` directory and create the database schema: - - .. code:: shell-session - - $ cd /path/to/paperless/src - $ python3 manage.py migrate - - This will not copy any data yet. - -4. Dump your data from SQLite: - - .. code:: shell-session - - $ python3 manage.py dumpdata --database=sqlite --exclude=contenttypes --exclude=auth.Permission > data.json - -5. Load your data into PostgreSQL: - - .. code:: shell-session - - $ python3 manage.py loaddata data.json - -6. If operating inside Docker, you may exit the shell now. - - .. code:: shell-session - - $ exit - -7. Start paperless. - - -Moving back to Paperless -======================== - -Lets say you migrated to Paperless-ngx and used it for a while, but decided that -you don't like it and want to move back (If you do, send me a mail about what -part you didn't like!), you can totally do that with a few simple steps. - -Paperless-ngx modified the database schema slightly, however, these changes can -be reverted while keeping your current data, so that your current data will -be compatible with original Paperless. - -Execute this: - -.. code:: shell-session - - $ cd /path/to/paperless - $ docker-compose run --rm webserver migrate documents 0023 - -Or without docker: - -.. code:: shell-session - - $ cd /path/to/paperless/src - $ python3 manage.py migrate documents 0023 - -After that, you need to clear your cookies (Paperless-ngx comes with updated -dependencies that do cookie-processing differently) and probably your cache -as well. - -.. _setup-less_powerful_devices: - - -Considerations for less powerful devices -######################################## - -Paperless runs on Raspberry Pi. However, some things are rather slow on the Pi and -configuring some options in paperless can help improve performance immensely: - -* Stick with SQLite to save some resources. -* Consider setting ``PAPERLESS_OCR_PAGES`` to 1, so that paperless will only OCR - the first page of your documents. In most cases, this page contains enough - information to be able to find it. -* ``PAPERLESS_TASK_WORKERS`` and ``PAPERLESS_THREADS_PER_WORKER`` are configured - to use all cores. The Raspberry Pi models 3 and up have 4 cores, meaning that - paperless will use 2 workers and 2 threads per worker. This may result in - sluggish response times during consumption, so you might want to lower these - settings (example: 2 workers and 1 thread to always have some computing power - left for other tasks). -* Keep ``PAPERLESS_OCR_MODE`` at its default value ``skip`` and consider OCR'ing - your documents before feeding them into paperless. Some scanners are able to - do this! You might want to even specify ``skip_noarchive`` to skip archive - file generation for already ocr'ed documents entirely. -* If you want to perform OCR on the device, consider using ``PAPERLESS_OCR_CLEAN=none``. - This will speed up OCR times and use less memory at the expense of slightly worse - OCR results. -* If using docker, consider setting ``PAPERLESS_WEBSERVER_WORKERS`` to - 1. This will save some memory. -* Consider setting ``PAPERLESS_ENABLE_NLTK`` to false, to disable the more - advanced language processing, which can take more memory and processing time. - -For details, refer to :ref:`configuration`. - -.. note:: - - Updating the :ref:`automatic matching algorithm ` - takes quite a bit of time. However, the update mechanism checks if your - data has changed before doing the heavy lifting. If you experience the - algorithm taking too much cpu time, consider changing the schedule in the - admin interface to daily. You can also manually invoke the task - by changing the date and time of the next run to today/now. - - The actual matching of the algorithm is fast and works on Raspberry Pi as - well as on any other device. - -.. _redis: https://redis.io/ - - -.. _setup-nginx: - -Using nginx as a reverse proxy -############################## - -If you want to expose paperless to the internet, you should hide it behind a -reverse proxy with SSL enabled. - -In addition to the usual configuration for SSL, -the following configuration is required for paperless to operate: - -.. code:: nginx - - http { - - # Adjust as required. This is the maximum size for file uploads. - # The default value 1M might be a little too small. - client_max_body_size 10M; - - server { - - location / { - - # Adjust host and port as required. - proxy_pass http://localhost:8000/; - - # These configuration options are required for WebSockets to work. - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - proxy_redirect off; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Host $server_name; - } - } - } - -The ``PAPERLESS_URL`` configuration variable is also required when using a reverse proxy. Please refer to the :ref:`hosting-and-security` docs. - -Also read `this `__, towards the end of the section. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 000000000..f522058a5 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,334 @@ +# Troubleshooting + +## No files are added by the consumer + +Check for the following issues: + +- Ensure that the directory you're putting your documents in is the + folder paperless is watching. With docker, this setting is performed + in the `docker-compose.yml` file. Without docker, look at the + `CONSUMPTION_DIR` setting. Don't adjust this setting if you're + using docker. + +- Ensure that redis is up and running. Paperless does its task + processing asynchronously, and for documents to arrive at the task + processor, it needs redis to run. + +- Ensure that the task processor is running. Docker does this + automatically. Manually invoke the task processor by executing + + ```shell-session + $ celery --app paperless worker + ``` + +- Look at the output of paperless and inspect it for any errors. + +- Go to the admin interface, and check if there are failed tasks. If + so, the tasks will contain an error message. + +## Consumer warns `OCR for XX failed` + +If you find the OCR accuracy to be too low, and/or the document consumer +warns that +`OCR for XX failed, but we're going to stick with what we've got since FORGIVING_OCR is enabled`, +then you might need to install the [Tesseract language +files](http://packages.ubuntu.com/search?keywords=tesseract-ocr) +marching your document's languages. + +As an example, if you are running Paperless-ngx from any Ubuntu or +Debian box, and your documents are written in Spanish you may need to +run: + + apt-get install -y tesseract-ocr-spa + +## Consumer fails to pickup any new files + +If you notice that the consumer will only pickup files in the +consumption directory at startup, but won't find any other files added +later, you will need to enable filesystem polling with the configuration +option `PAPERLESS_CONSUMER_POLLING`, see +`[here](/configuration#polling). + +This will disable listening to filesystem changes with inotify and +paperless will manually check the consumption directory for changes +instead. + +## Paperless always redirects to /admin + +You probably had the old paperless installed at some point. Paperless +installed a permanent redirect to /admin in your browser, and you need +to clear your browsing data / cache to fix that. + +## Operation not permitted + +You might see errors such as: + +```shell-session +chown: changing ownership of '../export': Operation not permitted +``` + +The container tries to set file ownership on the listed directories. +This is required so that the user running paperless inside docker has +write permissions to these folders. This happens when pointing these +directories to NFS shares, for example. + +Ensure that `chown` is possible on these directories. + +## Classifier error: No training data available + +This indicates that the Auto matching algorithm found no documents to +learn from. This may have two reasons: + +- You don't use the Auto matching algorithm: The error can be safely + ignored in this case. +- You are using the Auto matching algorithm: The classifier explicitly + excludes documents with Inbox tags. Verify that there are documents + in your archive without inbox tags. The algorithm will only learn + from documents not in your inbox. + +## UserWarning in sklearn on every single document + +You may encounter warnings like this: + +``` +/usr/local/lib/python3.7/site-packages/sklearn/base.py:315: +UserWarning: Trying to unpickle estimator CountVectorizer from version 0.23.2 when using version 0.24.0. +This might lead to breaking code or invalid results. Use at your own risk. +``` + +This happens when certain dependencies of paperless that are responsible +for the auto matching algorithm are updated. After updating these, your +current training data _might_ not be compatible anymore. This can be +ignored in most cases. This warning will disappear automatically when +paperless updates the training data. + +If you want to get rid of the warning or actually experience issues with +automatic matching, delete the file `classification_model.pickle` in the +data directory and let paperless recreate it. + +## 504 Server Error: Gateway Timeout when adding Office documents + +You may experience these errors when using the optional TIKA +integration: + +``` +requests.exceptions.HTTPError: 504 Server Error: Gateway Timeout for url: http://gotenberg:3000/forms/libreoffice/convert +``` + +Gotenberg is a server that converts Office documents into PDF documents +and has a default timeout of 30 seconds. When conversion takes longer, +Gotenberg raises this error. + +You can increase the timeout by configuring a command flag for Gotenberg +(see also [here](https://gotenberg.dev/docs/modules/api#properties)). If +using docker-compose, this is achieved by the following configuration +change in the `docker-compose.yml` file: + +```yaml +# The gotenberg chromium route is used to convert .eml files. We do not +# want to allow external content like tracking pixels or even javascript. +command: + - 'gotenberg' + - '--chromium-disable-javascript=true' + - '--chromium-allow-list=file:///tmp/.*' + - '--api-timeout=60' +``` + +## Permission denied errors in the consumption directory + +You might encounter errors such as: + +```shell-session +The following error occured while consuming document.pdf: [Errno 13] Permission denied: '/usr/src/paperless/src/../consume/document.pdf' +``` + +This happens when paperless does not have permission to delete files +inside the consumption directory. Ensure that `USERMAP_UID` and +`USERMAP_GID` are set to the user id and group id you use on the host +operating system, if these are different from `1000`. See [Docker setup](setup#docker_hub). + +Also ensure that you are able to read and write to the consumption +directory on the host. + +## OSError: \[Errno 19\] No such device when consuming files + +If you experience errors such as: + +```shell-session +File "/usr/local/lib/python3.7/site-packages/whoosh/codec/base.py", line 570, in open_compound_file +return CompoundStorage(dbfile, use_mmap=storage.supports_mmap) +File "/usr/local/lib/python3.7/site-packages/whoosh/filedb/compound.py", line 75, in __init__ +self._source = mmap.mmap(fileno, 0, access=mmap.ACCESS_READ) +OSError: [Errno 19] No such device + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): +File "/usr/local/lib/python3.7/site-packages/django_q/cluster.py", line 436, in worker +res = f(*task["args"], **task["kwargs"]) +File "/usr/src/paperless/src/documents/tasks.py", line 73, in consume_file +override_tag_ids=override_tag_ids) +File "/usr/src/paperless/src/documents/consumer.py", line 271, in try_consume_file +raise ConsumerError(e) +``` + +Paperless uses a search index to provide better and faster full text +searching. This search index is stored inside the `data` folder. The +search index uses memory-mapped files (mmap). The above error indicates +that paperless was unable to create and open these files. + +This happens when you're trying to store the data directory on certain +file systems (mostly network shares) that don't support memory-mapped +files. + +## Web-UI stuck at "Loading\..." + +This might have multiple reasons. + +1. If you built the docker image yourself or deployed using the bare + metal route, make sure that there are files in + `/static/frontend//`. If there are no + files, make sure that you executed `collectstatic` successfully, + either manually or as part of the docker image build. + + If the front end is still missing, make sure that the front end is + compiled (files present in `src/documents/static/frontend`). If it + is not, you need to compile the front end yourself or download the + release archive instead of cloning the repository. + +2. Check the output of the web server. You might see errors like this: + + ``` + [2021-01-25 10:08:04 +0000] [40] [ERROR] Socket error processing request. + Traceback (most recent call last): + File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 134, in handle + self.handle_request(listener, req, client, addr) + File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 190, in handle_request + util.reraise(*sys.exc_info()) + File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 625, in reraise + raise value + File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 178, in handle_request + resp.write_file(respiter) + File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 396, in write_file + if not self.sendfile(respiter): + File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 386, in sendfile + sent += os.sendfile(sockno, fileno, offset + sent, count) + OSError: [Errno 22] Invalid argument + ``` + + To fix this issue, add + + ``` + SENDFILE=0 + ``` + + to your [docker-compose.env]{.title-ref} file. + +## Error while reading metadata + +You might find messages like these in your log files: + +``` +[WARNING] [paperless.parsing.tesseract] Error while reading metadata +``` + +This indicates that paperless failed to read PDF metadata from one of +your documents. This happens when you open the affected documents in +paperless for editing. Paperless will continue to work, and will simply +not show the invalid metadata. + +## Consumer fails with a FileNotFoundError + +You might find messages like these in your log files: + +``` +[ERROR] [paperless.consumer] Error while consuming document SCN_0001.pdf: FileNotFoundError: [Errno 2] No such file or directory: '/tmp/ocrmypdf.io.yhk3zbv0/origin.pdf' +Traceback (most recent call last): + File "/app/paperless/src/paperless_tesseract/parsers.py", line 261, in parse + ocrmypdf.ocr(**args) + File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/api.py", line 337, in ocr + return run_pipeline(options=options, plugin_manager=plugin_manager, api=True) + File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/_sync.py", line 385, in run_pipeline + exec_concurrent(context, executor) + File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/_sync.py", line 302, in exec_concurrent + pdf = post_process(pdf, context, executor) + File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/_sync.py", line 235, in post_process + pdf_out = metadata_fixup(pdf_out, context) + File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/_pipeline.py", line 798, in metadata_fixup + with pikepdf.open(context.origin) as original, pikepdf.open(working_file) as pdf: + File "/usr/local/lib/python3.8/dist-packages/pikepdf/_methods.py", line 923, in open + pdf = Pdf._open( +FileNotFoundError: [Errno 2] No such file or directory: '/tmp/ocrmypdf.io.yhk3zbv0/origin.pdf' +``` + +This probably indicates paperless tried to consume the same file twice. +This can happen for a number of reasons, depending on how documents are +placed into the consume folder. If paperless is using inotify (the +default) to check for documents, try adjusting the +[inotify configuration](/configuration#inotify). If polling is enabled, try adjusting the +[polling configuration](/configuration#polling). + +## Consumer fails waiting for file to remain unmodified. + +You might find messages like these in your log files: + +``` +[ERROR] [paperless.management.consumer] Timeout while waiting on file /usr/src/paperless/src/../consume/SCN_0001.pdf to remain unmodified. +``` + +This indicates paperless timed out while waiting for the file to be +completely written to the consume folder. Adjusting +[polling configuration](/configuration#polling) values should resolve the issue. + +!!! note + + The user will need to manually move the file out of the consume folder + and back in, for the initial failing file to be consumed. + +## Consumer fails reporting "OS reports file as busy still". + +You might find messages like these in your log files: + +``` +[WARNING] [paperless.management.consumer] Not consuming file /usr/src/paperless/src/../consume/SCN_0001.pdf: OS reports file as busy still +``` + +This indicates paperless was unable to open the file, as the OS reported +the file as still being in use. To prevent a crash, paperless did not +try to consume the file. If paperless is using inotify (the default) to +check for documents, try adjusting the +[inotify configuration](/configuration#inotify). If polling is enabled, try adjusting the +[polling configuration](/configuration#polling). + +!!! note + + The user will need to manually move the file out of the consume folder + and back in, for the initial failing file to be consumed. + +## Log reports "Creating PaperlessTask failed". + +You might find messages like these in your log files: + +``` +[ERROR] [paperless.management.consumer] Creating PaperlessTask failed: db locked +``` + +You are likely using an sqlite based installation, with an increased +number of workers and are running into sqlite's concurrency +limitations. Uploading or consuming multiple files at once results in +many workers attempting to access the database simultaneously. + +Consider changing to the PostgreSQL database if you will be processing +many documents at once often. Otherwise, try tweaking the +`PAPERLESS_DB_TIMEOUT` setting to allow more time for the database to +unlock. This may have minor performance implications. + +## gunicorn fails to start with "is not a valid port number" + +You are likely running using Kubernetes, which automatically creates an +environment variable named [\${serviceName}\_PORT]{.title-ref}. This is +the same environment variable which is used by Paperless to optionally +change the port gunicorn listens on. + +To fix this, set [PAPERLESS_PORT]{.title-ref} again to your desired +port, or the default of 8000. diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst deleted file mode 100644 index 2d10bb15f..000000000 --- a/docs/troubleshooting.rst +++ /dev/null @@ -1,319 +0,0 @@ -*************** -Troubleshooting -*************** - -No files are added by the consumer -################################## - -Check for the following issues: - -* Ensure that the directory you're putting your documents in is the folder - paperless is watching. With docker, this setting is performed in the - ``docker-compose.yml`` file. Without docker, look at the ``CONSUMPTION_DIR`` - setting. Don't adjust this setting if you're using docker. -* Ensure that redis is up and running. Paperless does its task processing - asynchronously, and for documents to arrive at the task processor, it needs - redis to run. -* Ensure that the task processor is running. Docker does this automatically. - Manually invoke the task processor by executing - - .. code:: shell-session - - $ celery --app paperless worker - -* Look at the output of paperless and inspect it for any errors. -* Go to the admin interface, and check if there are failed tasks. If so, the - tasks will contain an error message. - -Consumer warns ``OCR for XX failed`` -#################################### - -If you find the OCR accuracy to be too low, and/or the document consumer warns -that ``OCR for XX failed, but we're going to stick with what we've got since -FORGIVING_OCR is enabled``, then you might need to install the -`Tesseract language files `_ -marching your document's languages. - -As an example, if you are running Paperless-ngx from any Ubuntu or Debian -box, and your documents are written in Spanish you may need to run:: - - apt-get install -y tesseract-ocr-spa - -Consumer fails to pickup any new files -###################################### - -If you notice that the consumer will only pickup files in the consumption -directory at startup, but won't find any other files added later, you will need to -enable filesystem polling with the configuration option -``PAPERLESS_CONSUMER_POLLING``, see :ref:`here `. - -This will disable listening to filesystem changes with inotify and paperless will -manually check the consumption directory for changes instead. - - -Paperless always redirects to /admin -#################################### - -You probably had the old paperless installed at some point. Paperless installed -a permanent redirect to /admin in your browser, and you need to clear your -browsing data / cache to fix that. - - -Operation not permitted -####################### - -You might see errors such as: - -.. code:: shell-session - - chown: changing ownership of '../export': Operation not permitted - -The container tries to set file ownership on the listed directories. This is -required so that the user running paperless inside docker has write permissions -to these folders. This happens when pointing these directories to NFS shares, -for example. - -Ensure that ``chown`` is possible on these directories. - - -Classifier error: No training data available -############################################ - -This indicates that the Auto matching algorithm found no documents to learn from. -This may have two reasons: - -* You don't use the Auto matching algorithm: The error can be safely ignored in this case. -* You are using the Auto matching algorithm: The classifier explicitly excludes documents - with Inbox tags. Verify that there are documents in your archive without inbox tags. - The algorithm will only learn from documents not in your inbox. - - -UserWarning in sklearn on every single document -############################################### - -You may encounter warnings like this: - -.. code:: - - /usr/local/lib/python3.7/site-packages/sklearn/base.py:315: - UserWarning: Trying to unpickle estimator CountVectorizer from version 0.23.2 when using version 0.24.0. - This might lead to breaking code or invalid results. Use at your own risk. - -This happens when certain dependencies of paperless that are responsible for the auto matching algorithm are -updated. After updating these, your current training data *might* not be compatible anymore. This can be ignored -in most cases. This warning will disappear automatically when paperless updates the training data. - -If you want to get rid of the warning or actually experience issues with automatic matching, delete -the file ``classification_model.pickle`` in the data directory and let paperless recreate it. - - -504 Server Error: Gateway Timeout when adding Office documents -############################################################## - -You may experience these errors when using the optional TIKA integration: - -.. code:: - - requests.exceptions.HTTPError: 504 Server Error: Gateway Timeout for url: http://gotenberg:3000/forms/libreoffice/convert - -Gotenberg is a server that converts Office documents into PDF documents and has a default timeout of 30 seconds. -When conversion takes longer, Gotenberg raises this error. - -You can increase the timeout by configuring a command flag for Gotenberg (see also `here `__). -If using docker-compose, this is achieved by the following configuration change in the ``docker-compose.yml`` file: - -.. code:: yaml - - gotenberg: - image: gotenberg/gotenberg:7.6 - restart: unless-stopped - command: - - "gotenberg" - - "--chromium-disable-routes=true" - - "--api-timeout=60" - -Permission denied errors in the consumption directory -##################################################### - -You might encounter errors such as: - -.. code:: shell-session - - The following error occured while consuming document.pdf: [Errno 13] Permission denied: '/usr/src/paperless/src/../consume/document.pdf' - -This happens when paperless does not have permission to delete files inside the consumption directory. -Ensure that ``USERMAP_UID`` and ``USERMAP_GID`` are set to the user id and group id you use on the host operating system, if these are -different from ``1000``. See :ref:`setup-docker_hub`. - -Also ensure that you are able to read and write to the consumption directory on the host. - - -OSError: [Errno 19] No such device when consuming files -####################################################### - -If you experience errors such as: - -.. code:: shell-session - - File "/usr/local/lib/python3.7/site-packages/whoosh/codec/base.py", line 570, in open_compound_file - return CompoundStorage(dbfile, use_mmap=storage.supports_mmap) - File "/usr/local/lib/python3.7/site-packages/whoosh/filedb/compound.py", line 75, in __init__ - self._source = mmap.mmap(fileno, 0, access=mmap.ACCESS_READ) - OSError: [Errno 19] No such device - - During handling of the above exception, another exception occurred: - - Traceback (most recent call last): - File "/usr/local/lib/python3.7/site-packages/django_q/cluster.py", line 436, in worker - res = f(*task["args"], **task["kwargs"]) - File "/usr/src/paperless/src/documents/tasks.py", line 73, in consume_file - override_tag_ids=override_tag_ids) - File "/usr/src/paperless/src/documents/consumer.py", line 271, in try_consume_file - raise ConsumerError(e) - -Paperless uses a search index to provide better and faster full text searching. This search index is stored inside -the ``data`` folder. The search index uses memory-mapped files (mmap). The above error indicates that paperless -was unable to create and open these files. - -This happens when you're trying to store the data directory on certain file systems (mostly network shares) -that don't support memory-mapped files. - - -Web-UI stuck at "Loading..." -############################ - -This might have multiple reasons. - - -1. If you built the docker image yourself or deployed using the bare metal route, - make sure that there are files in ``/static/frontend//``. - If there are no files, make sure that you executed ``collectstatic`` successfully, either - manually or as part of the docker image build. - - If the front end is still missing, make sure that the front end is compiled (files present in - ``src/documents/static/frontend``). If it is not, you need to compile the front end yourself - or download the release archive instead of cloning the repository. - -2. Check the output of the web server. You might see errors like this: - - - .. code:: - - [2021-01-25 10:08:04 +0000] [40] [ERROR] Socket error processing request. - Traceback (most recent call last): - File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 134, in handle - self.handle_request(listener, req, client, addr) - File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 190, in handle_request - util.reraise(*sys.exc_info()) - File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 625, in reraise - raise value - File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 178, in handle_request - resp.write_file(respiter) - File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 396, in write_file - if not self.sendfile(respiter): - File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 386, in sendfile - sent += os.sendfile(sockno, fileno, offset + sent, count) - OSError: [Errno 22] Invalid argument - - To fix this issue, add - - .. code:: - - SENDFILE=0 - - to your `docker-compose.env` file. - -Error while reading metadata -############################ - -You might find messages like these in your log files: - -.. code:: - - [WARNING] [paperless.parsing.tesseract] Error while reading metadata - -This indicates that paperless failed to read PDF metadata from one of your documents. This happens when you -open the affected documents in paperless for editing. Paperless will continue to work, and will simply not -show the invalid metadata. - -Consumer fails with a FileNotFoundError -####################################### - -You might find messages like these in your log files: - -.. code:: - - [ERROR] [paperless.consumer] Error while consuming document SCN_0001.pdf: FileNotFoundError: [Errno 2] No such file or directory: '/tmp/ocrmypdf.io.yhk3zbv0/origin.pdf' - Traceback (most recent call last): - File "/app/paperless/src/paperless_tesseract/parsers.py", line 261, in parse - ocrmypdf.ocr(**args) - File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/api.py", line 337, in ocr - return run_pipeline(options=options, plugin_manager=plugin_manager, api=True) - File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/_sync.py", line 385, in run_pipeline - exec_concurrent(context, executor) - File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/_sync.py", line 302, in exec_concurrent - pdf = post_process(pdf, context, executor) - File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/_sync.py", line 235, in post_process - pdf_out = metadata_fixup(pdf_out, context) - File "/usr/local/lib/python3.8/dist-packages/ocrmypdf/_pipeline.py", line 798, in metadata_fixup - with pikepdf.open(context.origin) as original, pikepdf.open(working_file) as pdf: - File "/usr/local/lib/python3.8/dist-packages/pikepdf/_methods.py", line 923, in open - pdf = Pdf._open( - FileNotFoundError: [Errno 2] No such file or directory: '/tmp/ocrmypdf.io.yhk3zbv0/origin.pdf' - -This probably indicates paperless tried to consume the same file twice. This can happen for a number of reasons, -depending on how documents are placed into the consume folder. If paperless is using inotify (the default) to -check for documents, try adjusting the :ref:`inotify configuration `. If polling is enabled, -try adjusting the :ref:`polling configuration `. - -Consumer fails waiting for file to remain unmodified. -##################################################### - -You might find messages like these in your log files: - -.. code:: - - [ERROR] [paperless.management.consumer] Timeout while waiting on file /usr/src/paperless/src/../consume/SCN_0001.pdf to remain unmodified. - -This indicates paperless timed out while waiting for the file to be completely written to the consume folder. -Adjusting :ref:`polling configuration ` values should resolve the issue. - -.. note:: - - The user will need to manually move the file out of the consume folder and - back in, for the initial failing file to be consumed. - -Consumer fails reporting "OS reports file as busy still". -######################################################### - -You might find messages like these in your log files: - -.. code:: - - [WARNING] [paperless.management.consumer] Not consuming file /usr/src/paperless/src/../consume/SCN_0001.pdf: OS reports file as busy still - -This indicates paperless was unable to open the file, as the OS reported the file as still being in use. To prevent a -crash, paperless did not try to consume the file. If paperless is using inotify (the default) to -check for documents, try adjusting the :ref:`inotify configuration `. If polling is enabled, -try adjusting the :ref:`polling configuration `. - -.. note:: - - The user will need to manually move the file out of the consume folder and - back in, for the initial failing file to be consumed. - -Log reports "Creating PaperlessTask failed". -######################################################### - -You might find messages like these in your log files: - -.. code:: - - [ERROR] [paperless.management.consumer] Creating PaperlessTask failed: db locked - -You are likely using an sqlite based installation, with an increased number of workers and are running into sqlite's concurrency limitations. -Uploading or consuming multiple files at once results in many workers attempting to access the database simultaneously. - -Consider changing to the PostgreSQL database if you will be processing many documents at once often. Otherwise, -try tweaking the ``PAPERLESS_DB_TIMEOUT`` setting to allow more time for the database to unlock. This may have -minor performance implications. diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 000000000..850648274 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,483 @@ +# Usage Overview + +Paperless is an application that manages your personal documents. With +the help of a document scanner (see [the scanners wiki](https://github.com/paperless-ngx/paperless-ngx/wiki/Scanner-&-Software-Recommendations)), paperless transforms your wieldy physical document binders +into a searchable archive and provides many utilities for finding and +managing your documents. + +## Terms and definitions + +Paperless essentially consists of two different parts for managing your +documents: + +- The _consumer_ watches a specified folder and adds all documents in + that folder to paperless. +- The _web server_ provides a UI that you use to manage and search for + your scanned documents. + +Each document has a couple of fields that you can assign to them: + +- A _Document_ is a piece of paper that sometimes contains valuable + information. +- The _correspondent_ of a document is the person, institution or + company that a document either originates from, or is sent to. +- A _tag_ is a label that you can assign to documents. Think of labels + as more powerful folders: Multiple documents can be grouped together + with a single tag, however, a single document can also have multiple + tags. This is not possible with folders. The reason folders are not + implemented in paperless is simply that tags are much more versatile + than folders. +- A _document type_ is used to demarcate the type of a document such + as letter, bank statement, invoice, contract, etc. It is used to + identify what a document is about. +- The _date added_ of a document is the date the document was scanned + into paperless. You cannot and should not change this date. +- The _date created_ of a document is the date the document was + initially issued. This can be the date you bought a product, the + date you signed a contract, or the date a letter was sent to you. +- The _archive serial number_ (short: ASN) of a document is the + identifier of the document in your physical document binders. See + [recommended workflow](#usage-reccomended_workflow) below. +- The _content_ of a document is the text that was OCR'ed from the + document. This text is fed into the search engine and is used for + matching tags, correspondents and document types. + +## Adding documents to paperless + +Once you've got Paperless setup, you need to start feeding documents +into it. When adding documents to paperless, it will perform the +following operations on your documents: + +1. OCR the document, if it has no text. Digital documents usually have + text, and this step will be skipped for those documents. +2. Paperless will create an archivable PDF/A document from your + document. If this document is coming from your scanner, it will have + embedded selectable text. +3. Paperless performs automatic matching of tags, correspondents and + types on the document before storing it in the database. + +!!! tip + + This process can be configured to fit your needs. If you don't want + paperless to create archived versions for digital documents, you can + configure that by configuring `PAPERLESS_OCR_MODE=skip_noarchive`. + Please read the + [relevant section in the documentation](/configuration#ocr). + +!!! note + + No matter which options you choose, Paperless will always store the + original document that it found in the consumption directory or in the + mail and will never overwrite that document. Archived versions are + stored alongside the original versions. + +### The consumption directory + +The primary method of getting documents into your database is by putting +them in the consumption directory. The consumer runs in an infinite +loop, looking for new additions to this directory. When it finds them, +the consumer goes about the process of parsing them with the OCR, +indexing what it finds, and storing it in the media directory. + +Getting stuff into this directory is up to you. If you're running +Paperless on your local computer, you might just want to drag and drop +files there, but if you're running this on a server and want your +scanner to automatically push files to this directory, you'll need to +setup some sort of service to accept the files from the scanner. +Typically, you're looking at an FTP server like +[Proftpd](http://www.proftpd.org/) or a Windows folder share with +[Samba](http://www.samba.org/). + +### Web UI Upload + +The dashboard has a file drop field to upload documents to paperless. +Simply drag a file onto this field or select a file with the file +dialog. Multiple files are supported. + +You can also upload documents on any other page of the web UI by +dragging-and-dropping files into your browser window. + +### Mobile upload {#usage-mobile_upload} + +The mobile app over at +allows Android users to share any documents with paperless. This can be +combined with any of the mobile scanning apps out there, such as Office +Lens. + +Furthermore, there is the [Paperless +App](https://github.com/bauerj/paperless_app) as well, which not only +has document upload, but also document browsing and download features. + +### IMAP (Email) {#usage-email} + +You can tell paperless-ngx to consume documents from your email +accounts. This is a very flexible and powerful feature, if you regularly +received documents via mail that you need to archive. The mail consumer +can be configured via the frontend settings (/settings/mail) in the following +manner: + +1. Define e-mail accounts. +2. Define mail rules for your account. + +These rules perform the following: + +1. Connect to the mail server. +2. Fetch all matching mails (as defined by folder, maximum age and the + filters) +3. Check if there are any consumable attachments. +4. If so, instruct paperless to consume the attachments and optionally + use the metadata provided in the rule for the new document. +5. If documents were consumed from a mail, the rule action is performed + on that mail. + +Paperless will completely ignore mails that do not match your filters. +It will also only perform the action on mails that it has consumed +documents from. + +The actions all ensure that the same mail is not consumed twice by +different means. These are as follows: + +- **Delete:** Immediately deletes mail that paperless has consumed + documents from. Use with caution. +- **Mark as read:** Mark consumed mail as read. Paperless will not + consume documents from already read mails. If you read a mail before + paperless sees it, it will be ignored. +- **Flag:** Sets the 'important' flag on mails with consumed + documents. Paperless will not consume flagged mails. +- **Move to folder:** Moves consumed mails out of the way so that + paperless wont consume them again. +- **Add custom Tag:** Adds a custom tag to mails with consumed + documents (the IMAP standard calls these "keywords"). Paperless + will not consume mails already tagged. Not all mail servers support + this feature! + +!!! warning + + The mail consumer will perform these actions on all mails it has + consumed documents from. Keep in mind that the actual consumption + process may fail for some reason, leaving you with missing documents in + paperless. + +!!! note + + With the correct set of rules, you can completely automate your email + documents. Create rules for every correspondent you receive digital + documents from and paperless will read them automatically. The default + action "mark as read" is pretty tame and will not cause any damage or + data loss whatsoever. + + You can also setup a special folder in your mail account for paperless + and use your favorite mail client to move to be consumed mails into that + folder automatically or manually and tell paperless to move them to yet + another folder after consumption. It's up to you. + +!!! note + + When defining a mail rule with a folder, you may need to try different + characters to define how the sub-folders are separated. Common values + include ".", "/" or "\|", but this varies by the mail server. + Check the documentation for your mail server. In the event of an error + fetching mail from a certain folder, check the Paperless logs. When a + folder is not located, Paperless will attempt to list all folders found + in the account to the Paperless logs. + +!!! note + + Paperless will process the rules in the order defined in the admin page. + + You can define catch-all rules and have them executed last to consume + any documents not matched by previous rules. Such a rule may assign an + "Unknown mail document" tag to consumed documents so you can inspect + them further. + +Paperless is set up to check your mails every 10 minutes. This can be +configured on the 'Scheduled tasks' page in the admin. + +### REST API + +You can also submit a document using the REST API, see [docs][api#file-uploads] +for details. + +## Best practices {#basic-searching} + +Paperless offers a couple tools that help you organize your document +collection. However, it is up to you to use them in a way that helps you +organize documents and find specific documents when you need them. This +section offers a couple ideas for managing your collection. + +Document types allow you to classify documents according to what they +are. You can define types such as "Receipt", "Invoice", or +"Contract". If you used to collect all your receipts in a single +binder, you can recreate that system in paperless by defining a document +type, assigning documents to that type and then filtering by that type +to only see all receipts. + +Not all documents need document types. Sometimes its hard to determine +what the type of a document is or it is hard to justify creating a +document type that you only need once or twice. This is okay. As long as +the types you define help you organize your collection in the way you +want, paperless is doing its job. + +Tags can be used in many different ways. Think of tags are more +versatile folders or binders. If you have a binder for documents related +to university / your car or health care, you can create these binders in +paperless by creating tags and assigning them to relevant documents. +Just as with documents, you can filter the document list by tags and +only see documents of a certain topic. + +With physical documents, you'll often need to decide which folder the +document belongs to. The advantage of tags over folders and binders is +that a single document can have multiple tags. A physical document +cannot magically appear in two different folders, but with tags, this is +entirely possible. + +!!! tip + + This can be used in many different ways. One example: Imagine you're + working on a particular task, such as signing up for university. Usually + you'll need to collect a bunch of different documents that are already + sorted into various folders. With the tag system of paperless, you can + create a new group of documents that are relevant to this task without + destroying the already existing organization. When you're done with the + task, you could delete the tag again, which would be equal to sorting + documents back into the folder they belong into. Or keep the tag, up to + you. + +All of the logic above applies to correspondents as well. Attach them to +documents if you feel that they help you organize your collection. + +When you've started organizing your documents, create a couple saved +views for document collections you regularly access. This is equal to +having labeled physical binders on your desk, except that these saved +views are dynamic and simply update themselves as you add documents to +the system. + +Here are a couple examples of tags and types that you could use in your +collection. + +- An `inbox` tag for newly added documents that you haven't manually + edited yet. +- A tag `car` for everything car related (repairs, registration, + insurance, etc) +- A tag `todo` for documents that you still need to do something with, + such as reply, or perform some task online. +- A tag `bank account x` for all bank statement related to that + account. +- A tag `mail` for anything that you added to paperless via its mail + processing capabilities. +- A tag `missing_metadata` when you still need to add some metadata to + a document, but can't or don't want to do this right now. + +## Searching {#basic-usage_searching} + +Paperless offers an extensive searching mechanism that is designed to +allow you to quickly find a document you're looking for (for example, +that thing that just broke and you bought a couple months ago, that +contract you signed 8 years ago). + +When you search paperless for a document, it tries to match this query +against your documents. Paperless will look for matching documents by +inspecting their content, title, correspondent, type and tags. Paperless +returns a scored list of results, so that documents matching your query +better will appear further up in the search results. + +By default, paperless returns only documents which contain all words +typed in the search bar. However, paperless also offers advanced search +syntax if you want to drill down the results further. + +Matching documents with logical expressions: + +``` +shopname AND (product1 OR product2) +``` + +Matching specific tags, correspondents or types: + +``` +type:invoice tag:unpaid +correspondent:university certificate +``` + +Matching dates: + +``` +created:[2005 to 2009] +added:yesterday +modified:today +``` + +Matching inexact words: + +``` +produ*name +``` + +!!! note + + Inexact terms are hard for search indexes. These queries might take a + while to execute. That's why paperless offers auto complete and query + correction. + +All of these constructs can be combined as you see fit. If you want to +learn more about the query language used by paperless, paperless uses +Whoosh's default query language. Head over to [Whoosh query +language](https://whoosh.readthedocs.io/en/latest/querylang.html). For +details on what date parsing utilities are available, see [Date +parsing](https://whoosh.readthedocs.io/en/latest/dates.html#parsing-date-queries). + +## The recommended workflow {#usage-recommended_workflow} + +Once you have familiarized yourself with paperless and are ready to use +it for all your documents, the recommended workflow for managing your +documents is as follows. This workflow also takes into account that some +documents have to be kept in physical form, but still ensures that you +get all the advantages for these documents as well. + +The following diagram shows how easy it is to manage your documents. + +![image](assets/recommended_workflow.png){width=400} + +### Preparations in paperless + +- Create an inbox tag that gets assigned to all new documents. +- Create a TODO tag. + +### Processing of the physical documents + +Keep a physical inbox. Whenever you receive a document that you need to +archive, put it into your inbox. Regularly, do the following for all +documents in your inbox: + +1. For each document, decide if you need to keep the document in + physical form. This applies to certain important documents, such as + contracts and certificates. +2. If you need to keep the document, write a running number on the + document before scanning, starting at one and counting upwards. This + is the archive serial number, or ASN in short. +3. Scan the document. +4. If the document has an ASN assigned, store it in a _single_ binder, + sorted by ASN. Don't order this binder in any other way. +5. If the document has no ASN, throw it away. Yay! + +Over time, you will notice that your physical binder will fill up. If it +is full, label the binder with the range of ASNs in this binder (i.e., +"Documents 1 to 343"), store the binder in your cellar or elsewhere, +and start a new binder. + +The idea behind this process is that you will never have to use the +physical binders to find a document. If you need a specific physical +document, you may find this document by: + +1. Searching in paperless for the document. +2. Identify the ASN of the document, since it appears on the scan. +3. Grab the relevant document binder and get the document. This is easy + since they are sorted by ASN. + +### Processing of documents in paperless + +Once you have scanned in a document, proceed in paperless as follows. + +1. If the document has an ASN, assign the ASN to the document. +2. Assign a correspondent to the document (i.e., your employer, bank, + etc) This isn't strictly necessary but helps in finding a document + when you need it. +3. Assign a document type (i.e., invoice, bank statement, etc) to the + document This isn't strictly necessary but helps in finding a + document when you need it. +4. Assign a proper title to the document (the name of an item you + bought, the subject of the letter, etc) +5. Check that the date of the document is correct. Paperless tries to + read the date from the content of the document, but this fails + sometimes if the OCR is bad or multiple dates appear on the + document. +6. Remove inbox tags from the documents. + +!!! tip + + You can setup manual matching rules for your correspondents and tags and + paperless will assign them automatically. After consuming a couple + documents, you can even ask paperless to *learn* when to assign tags and + correspondents by itself. For details on this feature, see + [advanced matching](advanced_usage#matching). + +### Task management + +Some documents require attention and require you to act on the document. +You may take two different approaches to handle these documents based on +how regularly you intend to scan documents and use paperless. + +- If you scan and process your documents in paperless regularly, + assign a TODO tag to all scanned documents that you need to process. + Create a saved view on the dashboard that shows all documents with + this tag. +- If you do not scan documents regularly and use paperless solely for + archiving, create a physical todo box next to your physical inbox + and put documents you need to process in the TODO box. When you + performed the task associated with the document, move it to the + inbox. + +## Architectue + +Paperless-ngx consists of the following components: + +- **The webserver:** This serves the administration pages, the API, + and the new frontend. This is the main tool you'll be using to interact + with paperless. You may start the webserver directly with + + ```shell-session + $ cd /path/to/paperless/src/ + $ gunicorn -c ../gunicorn.conf.py paperless.wsgi + ``` + + or by any other means such as Apache `mod_wsgi`. + +- **The consumer:** This is what watches your consumption folder for + documents. However, the consumer itself does not really consume your + documents. Now it notifies a task processor that a new file is ready + for consumption. I suppose it should be named differently. This was + also used to check your emails, but that's now done elsewhere as + well. + + Start the consumer with the management command `document_consumer`: + + ```shell-session + $ cd /path/to/paperless/src/ + $ python3 manage.py document_consumer + ``` + +- **The task processor:** Paperless relies on [Celery - Distributed + Task Queue](https://docs.celeryq.dev/en/stable/index.html) for doing + most of the heavy lifting. This is a task queue that accepts tasks + from multiple sources and processes these in parallel. It also comes + with a scheduler that executes certain commands periodically. + + This task processor is responsible for: + + - Consuming documents. When the consumer finds new documents, it + notifies the task processor to start a consumption task. + - The task processor also performs the consumption of any + documents you upload through the web interface. + - Consuming emails. It periodically checks your configured + accounts for new emails and notifies the task processor to + consume the attachment of an email. + - Maintaining the search index and the automatic matching + algorithm. These are things that paperless needs to do from time + to time in order to operate properly. + + This allows paperless to process multiple documents from your + consumption folder in parallel! On a modern multi core system, this + makes the consumption process with full OCR blazingly fast. + + The task processor comes with a built-in admin interface that you + can use to check whenever any of the tasks fail and inspect the + errors (i.e., wrong email credentials, errors during consuming a + specific file, etc). + +- A [redis](https://redis.io/) message broker: This is a really + lightweight service that is responsible for getting the tasks from + the webserver and the consumer to the task scheduler. These run in a + different process (maybe even on different machines!), and + therefore, this is necessary. + +- Optional: A database server. Paperless supports PostgreSQL, MariaDB + and SQLite for storing its data. diff --git a/docs/usage_overview.rst b/docs/usage_overview.rst deleted file mode 100644 index a321afb93..000000000 --- a/docs/usage_overview.rst +++ /dev/null @@ -1,420 +0,0 @@ -************** -Usage Overview -************** - -Paperless is an application that manages your personal documents. With -the help of a document scanner (see :ref:`scanners`), paperless transforms -your wieldy physical document binders into a searchable archive and -provides many utilities for finding and managing your documents. - - -Terms and definitions -##################### - -Paperless essentially consists of two different parts for managing your -documents: - -* The *consumer* watches a specified folder and adds all documents in that - folder to paperless. -* The *web server* provides a UI that you use to manage and search for your - scanned documents. - -Each document has a couple of fields that you can assign to them: - -* A *Document* is a piece of paper that sometimes contains valuable - information. -* The *correspondent* of a document is the person, institution or company that - a document either originates from, or is sent to. -* A *tag* is a label that you can assign to documents. Think of labels as more - powerful folders: Multiple documents can be grouped together with a single - tag, however, a single document can also have multiple tags. This is not - possible with folders. The reason folders are not implemented in paperless - is simply that tags are much more versatile than folders. -* A *document type* is used to demarcate the type of a document such as letter, - bank statement, invoice, contract, etc. It is used to identify what a document - is about. -* The *date added* of a document is the date the document was scanned into - paperless. You cannot and should not change this date. -* The *date created* of a document is the date the document was initially issued. - This can be the date you bought a product, the date you signed a contract, or - the date a letter was sent to you. -* The *archive serial number* (short: ASN) of a document is the identifier of - the document in your physical document binders. See - :ref:`usage-recommended_workflow` below. -* The *content* of a document is the text that was OCR'ed from the document. - This text is fed into the search engine and is used for matching tags, - correspondents and document types. - - -Frontend overview -################# - -.. warning:: - - TBD. Add some fancy screenshots! - -Adding documents to paperless -############################# - -Once you've got Paperless setup, you need to start feeding documents into it. -When adding documents to paperless, it will perform the following operations on -your documents: - -1. OCR the document, if it has no text. Digital documents usually have text, - and this step will be skipped for those documents. -2. Paperless will create an archivable PDF/A document from your document. - If this document is coming from your scanner, it will have embedded selectable text. -3. Paperless performs automatic matching of tags, correspondents and types on the - document before storing it in the database. - -.. hint:: - - This process can be configured to fit your needs. If you don't want paperless - to create archived versions for digital documents, you can configure that by - configuring ``PAPERLESS_OCR_MODE=skip_noarchive``. Please read the - :ref:`relevant section in the documentation `. - -.. note:: - - No matter which options you choose, Paperless will always store the original - document that it found in the consumption directory or in the mail and - will never overwrite that document. Archived versions are stored alongside the - original versions. - - -The consumption directory -========================= - -The primary method of getting documents into your database is by putting them in -the consumption directory. The consumer runs in an infinite loop, looking for new -additions to this directory. When it finds them, the consumer goes about the process -of parsing them with the OCR, indexing what it finds, and storing it in the media directory. - -Getting stuff into this directory is up to you. If you're running Paperless -on your local computer, you might just want to drag and drop files there, but if -you're running this on a server and want your scanner to automatically push -files to this directory, you'll need to setup some sort of service to accept the -files from the scanner. Typically, you're looking at an FTP server like -`Proftpd`_ or a Windows folder share with `Samba`_. - -.. _Proftpd: http://www.proftpd.org/ -.. _Samba: http://www.samba.org/ - -.. TODO: hyperref to configuration of the location of this magic folder. - -Web UI Upload -============= - -The dashboard has a file drop field to upload documents to paperless. Simply drag a file -onto this field or select a file with the file dialog. Multiple files are supported. - -You can also upload documents on any other page of the web UI by dragging-and-dropping -files into your browser window. - -.. _usage-mobile_upload: - -Mobile upload -============= - -The mobile app over at ``_ allows Android users -to share any documents with paperless. This can be combined with any of the mobile -scanning apps out there, such as Office Lens. - -Furthermore, there is the `Paperless App `_ as well, -which not only has document upload, but also document browsing and download features. - -.. _usage-email: - -IMAP (Email) -============ - -You can tell paperless-ngx to consume documents from your email accounts. -This is a very flexible and powerful feature, if you regularly received documents -via mail that you need to archive. The mail consumer can be configured by using the -admin interface in the following manner: - -1. Define e-mail accounts. -2. Define mail rules for your account. - -These rules perform the following: - -1. Connect to the mail server. -2. Fetch all matching mails (as defined by folder, maximum age and the filters) -3. Check if there are any consumable attachments. -4. If so, instruct paperless to consume the attachments and optionally - use the metadata provided in the rule for the new document. -5. If documents were consumed from a mail, the rule action is performed - on that mail. - -Paperless will completely ignore mails that do not match your filters. It will also -only perform the action on mails that it has consumed documents from. - -The actions all ensure that the same mail is not consumed twice by different means. -These are as follows: - -* **Delete:** Immediately deletes mail that paperless has consumed documents from. - Use with caution. -* **Mark as read:** Mark consumed mail as read. Paperless will not consume documents - from already read mails. If you read a mail before paperless sees it, it will be - ignored. -* **Flag:** Sets the 'important' flag on mails with consumed documents. Paperless - will not consume flagged mails. -* **Move to folder:** Moves consumed mails out of the way so that paperless wont - consume them again. -* **Add custom Tag:** Adds a custom tag to mails with consumed documents (the IMAP - standard calls these "keywords"). Paperless will not consume mails already tagged. - Not all mail servers support this feature! - -.. caution:: - - The mail consumer will perform these actions on all mails it has consumed - documents from. Keep in mind that the actual consumption process may fail - for some reason, leaving you with missing documents in paperless. - -.. note:: - - With the correct set of rules, you can completely automate your email documents. - Create rules for every correspondent you receive digital documents from and - paperless will read them automatically. The default action "mark as read" is - pretty tame and will not cause any damage or data loss whatsoever. - - You can also setup a special folder in your mail account for paperless and use - your favorite mail client to move to be consumed mails into that folder - automatically or manually and tell paperless to move them to yet another folder - after consumption. It's up to you. - -.. note:: - - When defining a mail rule with a folder, you may need to try different characters to - define how the sub-folders are separated. Common values include ".", "/" or "|", but - this varies by the mail server. Check the documentation for your mail server. In the - event of an error fetching mail from a certain folder, check the Paperless logs. When - a folder is not located, Paperless will attempt to list all folders found in the account - to the Paperless logs. - -.. note:: - - Paperless will process the rules in the order defined in the admin page. - - You can define catch-all rules and have them executed last to consume - any documents not matched by previous rules. Such a rule may assign an "Unknown - mail document" tag to consumed documents so you can inspect them further. - -Paperless is set up to check your mails every 10 minutes. This can be configured on the -'Scheduled tasks' page in the admin. - - -REST API -======== - -You can also submit a document using the REST API, see :ref:`api-file_uploads` for details. - -.. _basic-searching: - - -Best practices -############## - -Paperless offers a couple tools that help you organize your document collection. However, -it is up to you to use them in a way that helps you organize documents and find specific -documents when you need them. This section offers a couple ideas for managing your collection. - -Document types allow you to classify documents according to what they are. You can define -types such as "Receipt", "Invoice", or "Contract". If you used to collect all your receipts -in a single binder, you can recreate that system in paperless by defining a document type, -assigning documents to that type and then filtering by that type to only see all receipts. - -Not all documents need document types. Sometimes its hard to determine what the type of a -document is or it is hard to justify creating a document type that you only need once or twice. -This is okay. As long as the types you define help you organize your collection in the way -you want, paperless is doing its job. - -Tags can be used in many different ways. Think of tags are more versatile folders or binders. -If you have a binder for documents related to university / your car or health care, you can -create these binders in paperless by creating tags and assigning them to relevant documents. -Just as with documents, you can filter the document list by tags and only see documents of -a certain topic. - -With physical documents, you'll often need to decide which folder the document belongs to. -The advantage of tags over folders and binders is that a single document can have multiple -tags. A physical document cannot magically appear in two different folders, but with tags, -this is entirely possible. - -.. hint:: - - This can be used in many different ways. One example: Imagine you're working on a particular - task, such as signing up for university. Usually you'll need to collect a bunch of different - documents that are already sorted into various folders. With the tag system of paperless, - you can create a new group of documents that are relevant to this task without destroying - the already existing organization. When you're done with the task, you could delete the - tag again, which would be equal to sorting documents back into the folder they belong into. - Or keep the tag, up to you. - -All of the logic above applies to correspondents as well. Attach them to documents if you -feel that they help you organize your collection. - -When you've started organizing your documents, create a couple saved views for document collections -you regularly access. This is equal to having labeled physical binders on your desk, except -that these saved views are dynamic and simply update themselves as you add documents to the system. - -Here are a couple examples of tags and types that you could use in your collection. - -* An ``inbox`` tag for newly added documents that you haven't manually edited yet. -* A tag ``car`` for everything car related (repairs, registration, insurance, etc) -* A tag ``todo`` for documents that you still need to do something with, such as reply, or - perform some task online. -* A tag ``bank account x`` for all bank statement related to that account. -* A tag ``mail`` for anything that you added to paperless via its mail processing capabilities. -* A tag ``missing_metadata`` when you still need to add some metadata to a document, but can't - or don't want to do this right now. - -.. _basic-usage_searching: - -Searching -######### - -Paperless offers an extensive searching mechanism that is designed to allow you to quickly -find a document you're looking for (for example, that thing that just broke and you bought -a couple months ago, that contract you signed 8 years ago). - -When you search paperless for a document, it tries to match this query against your documents. -Paperless will look for matching documents by inspecting their content, title, correspondent, -type and tags. Paperless returns a scored list of results, so that documents matching your query -better will appear further up in the search results. - -By default, paperless returns only documents which contain all words typed in the search bar. -However, paperless also offers advanced search syntax if you want to drill down the results -further. - -Matching documents with logical expressions: - -.. code:: - - shopname AND (product1 OR product2) - -Matching specific tags, correspondents or types: - -.. code:: - - type:invoice tag:unpaid - correspondent:university certificate - -Matching dates: - -.. code:: - - created:[2005 to 2009] - added:yesterday - modified:today - -Matching inexact words: - -.. code:: - - produ*name - -.. note:: - - Inexact terms are hard for search indexes. These queries might take a while to execute. That's why paperless offers - auto complete and query correction. - -All of these constructs can be combined as you see fit. -If you want to learn more about the query language used by paperless, paperless uses Whoosh's default query language. -Head over to `Whoosh query language `_. -For details on what date parsing utilities are available, see -`Date parsing `_. - - -.. _usage-recommended_workflow: - -The recommended workflow -######################## - -Once you have familiarized yourself with paperless and are ready to use it -for all your documents, the recommended workflow for managing your documents -is as follows. This workflow also takes into account that some documents -have to be kept in physical form, but still ensures that you get all the -advantages for these documents as well. - -The following diagram shows how easy it is to manage your documents. - -.. image:: _static/recommended_workflow.png - -Preparations in paperless -========================= - -* Create an inbox tag that gets assigned to all new documents. -* Create a TODO tag. - -Processing of the physical documents -==================================== - -Keep a physical inbox. Whenever you receive a document that you need to -archive, put it into your inbox. Regularly, do the following for all documents -in your inbox: - -1. For each document, decide if you need to keep the document in physical - form. This applies to certain important documents, such as contracts and - certificates. -2. If you need to keep the document, write a running number on the document - before scanning, starting at one and counting upwards. This is the archive - serial number, or ASN in short. -3. Scan the document. -4. If the document has an ASN assigned, store it in a *single* binder, sorted - by ASN. Don't order this binder in any other way. -5. If the document has no ASN, throw it away. Yay! - -Over time, you will notice that your physical binder will fill up. If it is -full, label the binder with the range of ASNs in this binder (i.e., "Documents -1 to 343"), store the binder in your cellar or elsewhere, and start a new -binder. - -The idea behind this process is that you will never have to use the physical -binders to find a document. If you need a specific physical document, you -may find this document by: - -1. Searching in paperless for the document. -2. Identify the ASN of the document, since it appears on the scan. -3. Grab the relevant document binder and get the document. This is easy since - they are sorted by ASN. - -Processing of documents in paperless -==================================== - -Once you have scanned in a document, proceed in paperless as follows. - -1. If the document has an ASN, assign the ASN to the document. -2. Assign a correspondent to the document (i.e., your employer, bank, etc) - This isn't strictly necessary but helps in finding a document when you need - it. -3. Assign a document type (i.e., invoice, bank statement, etc) to the document - This isn't strictly necessary but helps in finding a document when you need - it. -4. Assign a proper title to the document (the name of an item you bought, the - subject of the letter, etc) -5. Check that the date of the document is correct. Paperless tries to read - the date from the content of the document, but this fails sometimes if the - OCR is bad or multiple dates appear on the document. -6. Remove inbox tags from the documents. - -.. hint:: - - You can setup manual matching rules for your correspondents and tags and - paperless will assign them automatically. After consuming a couple documents, - you can even ask paperless to *learn* when to assign tags and correspondents - by itself. For details on this feature, see :ref:`advanced-matching`. - -Task management -=============== - -Some documents require attention and require you to act on the document. You -may take two different approaches to handle these documents based on how -regularly you intend to scan documents and use paperless. - -* If you scan and process your documents in paperless regularly, assign a - TODO tag to all scanned documents that you need to process. Create a saved - view on the dashboard that shows all documents with this tag. -* If you do not scan documents regularly and use paperless solely for archiving, - create a physical todo box next to your physical inbox and put documents you - need to process in the TODO box. When you performed the task associated with - the document, move it to the inbox. diff --git a/install-paperless-ngx.sh b/install-paperless-ngx.sh index d5266efca..bbdc6025f 100755 --- a/install-paperless-ngx.sh +++ b/install-paperless-ngx.sh @@ -95,6 +95,7 @@ echo "============================" echo "" echo "The URL paperless will be available at. This is required if the" echo "installation will be accessible via the web, otherwise can be left blank." +echo "Example: https://paperless.example.com" echo "" ask "URL" "" @@ -112,6 +113,8 @@ echo "" echo "Paperless requires you to configure the current time zone correctly." echo "Otherwise, the dates of your documents may appear off by one day," echo "depending on where you are on earth." +echo "Example: Europe/Berlin" +echo "See here for a list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones" echo "" ask "Current time zone" "$default_time_zone" diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 000000000..9de918b5b --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,62 @@ +site_name: Paperless-ngx +theme: + name: material + logo: assets/logo.svg + font: + text: Roboto + code: Roboto Mono + palette: + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to light mode + features: + - navigation.tabs + - navigation.top + - toc.integrate + icon: + repo: fontawesome/brands/github + favicon: assets/favicon.png +repo_url: https://github.com/paperless-ngx/paperless-ngx +edit_uri: blob/main/docs/ +extra_css: + - assets/extra.css +markdown_extensions: + - attr_list + - md_in_html + - def_list + - admonition + - tables + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.superfences +nav: + - index.md + - setup.md + - 'Basic Usage': usage.md + - configuration.md + - administration.md + - advanced_usage.md + - 'REST API': api.md + - development.md + - 'FAQs': faq.md + - troubleshooting.md + - changelog.md +copyright: Copyright © 2016 - 2022 Daniel Quinn, Jonas Winkler, and the Paperless-ngx team +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/paperless-ngx/paperless-ngx + - icon: fontawesome/brands/docker + link: https://hub.docker.com/r/paperlessngx/paperless-ngx + - icon: material/chat + link: https://matrix.to/#/#paperless:matrix.org diff --git a/paperless.conf.example b/paperless.conf.example index 26fc327c3..524d9264e 100644 --- a/paperless.conf.example +++ b/paperless.conf.example @@ -1,5 +1,5 @@ # Have a look at the docs for documentation. -# https://paperless-ngx.readthedocs.io/en/latest/configuration.html +# https://docs.paperless-ngx.com/configuration/ # Debug. Only enable this for development. diff --git a/scripts/start_services.sh b/scripts/start_services.sh index 97ef0cba7..d53698a27 100755 --- a/scripts/start_services.sh +++ b/scripts/start_services.sh @@ -2,5 +2,5 @@ docker run -p 5432:5432 -e POSTGRES_PASSWORD=password -v paperless_pgdata:/var/lib/postgresql/data -d postgres:13 docker run -d -p 6379:6379 redis:latest -docker run -p 3000:3000 -d gotenberg/gotenberg:7.6 +docker run -p 3000:3000 -d gotenberg/gotenberg:7.6 gotenberg --chromium-disable-javascript=true --chromium-allow-list="file:///tmp/.*" docker run -p 9998:9998 -d ghcr.io/paperless-ngx/tika:latest diff --git a/src-ui/cypress/e2e/settings/settings.cy.ts b/src-ui/cypress/e2e/settings/settings.cy.ts index 0f5519f84..0f46df9a4 100644 --- a/src-ui/cypress/e2e/settings/settings.cy.ts +++ b/src-ui/cypress/e2e/settings/settings.cy.ts @@ -35,6 +35,16 @@ describe('settings', () => { req.reply(response) } ).as('savedViews') + + cy.intercept('http://localhost:8000/api/mail_accounts/*', { + fixture: 'mail_accounts/mail_accounts.json', + }) + cy.intercept('http://localhost:8000/api/mail_rules/*', { + fixture: 'mail_rules/mail_rules.json', + }).as('mailRules') + cy.intercept('http://localhost:8000/api/tasks/', { + fixture: 'tasks/tasks.json', + }) }) cy.fixture('documents/documents.json').then((documentsJson) => { @@ -48,7 +58,6 @@ describe('settings', () => { cy.viewport(1024, 1600) cy.visit('/settings') - cy.wait('@savedViews') }) it('should activate / deactivate save button when settings change and are saved', () => { @@ -77,16 +86,16 @@ describe('settings', () => { }) it('should remove saved view from sidebar when unset', () => { - cy.contains('a', 'Saved views').click() + cy.contains('a', 'Saved views').click().wait(2000) cy.get('#show_in_sidebar_1').click() - cy.contains('button', 'Save').click().wait('@savedViews') + cy.contains('button', 'Save').click().wait('@savedViews').wait(2000) cy.contains('li', 'Inbox').should('not.exist') }) it('should remove saved view from dashboard when unset', () => { cy.contains('a', 'Saved views').click() cy.get('#show_on_dashboard_1').click() - cy.contains('button', 'Save').click().wait('@savedViews') + cy.contains('button', 'Save').click().wait('@savedViews').wait(2000) cy.visit('/dashboard') cy.get('app-saved-view-widget').contains('Inbox').should('not.exist') }) diff --git a/src-ui/cypress/e2e/tasks/tasks.cy.ts b/src-ui/cypress/e2e/tasks/tasks.cy.ts index b68de3be1..08c3b36b5 100644 --- a/src-ui/cypress/e2e/tasks/tasks.cy.ts +++ b/src-ui/cypress/e2e/tasks/tasks.cy.ts @@ -44,6 +44,39 @@ describe('tasks', () => { }) }) + it('should correctly switch between task tabs', () => { + cy.get('tbody').find('tr:visible').its('length').should('eq', 10) // double because collapsible result tr + cy.wait(500) // stabilizes the test, for some reason... + cy.get('app-tasks') + .find('a:visible') + .contains('Queued') + .first() + .click() + .wait(2000) + .then(() => { + cy.get('tbody').find('tr:visible').should('not.exist') + }) + cy.get('app-tasks') + .find('a:visible') + .contains('Started') + .first() + .click() + .wait(2000) + .then(() => { + cy.get('tbody').find('tr:visible').its('length').should('eq', 2) // double because collapsible result tr + }) + cy.get('app-tasks') + .find('a:visible') + .contains('Complete') + .first() + .click() + .wait('@tasks') + .wait(2000) + .then(() => { + cy.get('tbody').find('tr:visible').its('length').should('eq', 12) // double because collapsible result tr + }) + }) + it('should allow toggling all tasks in list and warn on dismiss', () => { cy.get('thead').find('input[type="checkbox"]').first().click() cy.get('body').find('button').contains('Dismiss selected').first().click() diff --git a/src-ui/cypress/fixtures/mail_accounts/mail_accounts.json b/src-ui/cypress/fixtures/mail_accounts/mail_accounts.json new file mode 100644 index 000000000..19c45b15a --- /dev/null +++ b/src-ui/cypress/fixtures/mail_accounts/mail_accounts.json @@ -0,0 +1,27 @@ +{ + "count": 2, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": "IMAP Server", + "imap_server": "imap.example.com", + "imap_port": 993, + "imap_security": 2, + "username": "inbox@example.com", + "password": "pass", + "character_set": "UTF-8" + }, + { + "id": 2, + "name": "Gmail", + "imap_server": "imap.gmail.com", + "imap_port": 993, + "imap_security": 2, + "username": "user@gmail.com", + "password": "pass", + "character_set": "UTF-8" + } + ] +} diff --git a/src-ui/cypress/fixtures/mail_rules/mail_rules.json b/src-ui/cypress/fixtures/mail_rules/mail_rules.json new file mode 100644 index 000000000..a2c59c5c6 --- /dev/null +++ b/src-ui/cypress/fixtures/mail_rules/mail_rules.json @@ -0,0 +1,29 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": "Gmail", + "account": 2, + "folder": "INBOX", + "filter_from": null, + "filter_subject": "[paperless]", + "filter_body": null, + "filter_attachment_filename": null, + "maximum_age": 30, + "action": 3, + "action_parameter": null, + "assign_title_from": 1, + "assign_tags": [ + 9 + ], + "assign_correspondent_from": 1, + "assign_correspondent": 2, + "assign_document_type": null, + "order": 0, + "attachment_type": 2 + } + ] +} diff --git a/src-ui/cypress/fixtures/saved_views/savedviews.json b/src-ui/cypress/fixtures/saved_views/savedviews.json index 003bd900a..64afcf3dc 100644 --- a/src-ui/cypress/fixtures/saved_views/savedviews.json +++ b/src-ui/cypress/fixtures/saved_views/savedviews.json @@ -1 +1,44 @@ -{"count":3,"next":null,"previous":null,"results":[{"id":1,"name":"Inbox","show_on_dashboard":true,"show_in_sidebar":true,"sort_field":"created","sort_reverse":true,"filter_rules":[{"rule_type":6,"value":"18"}]},{"id":2,"name":"Recently Added","show_on_dashboard":true,"show_in_sidebar":false,"sort_field":"created","sort_reverse":true,"filter_rules":[]},{"id":11,"name":"Taxes","show_on_dashboard":false,"show_in_sidebar":true,"sort_field":"created","sort_reverse":true,"filter_rules":[{"rule_type":6,"value":"39"}]}]} +{ + "count": 3, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": "Inbox", + "show_on_dashboard": true, + "show_in_sidebar": true, + "sort_field": "created", + "sort_reverse": true, + "filter_rules": [ + { + "rule_type": 6, + "value": "18" + } + ] + }, + { + "id": 2, + "name": "Recently Added", + "show_on_dashboard": true, + "show_in_sidebar": false, + "sort_field": "created", + "sort_reverse": true, + "filter_rules": [] + }, + { + "id": 11, + "name": "Taxes", + "show_on_dashboard": false, + "show_in_sidebar": true, + "sort_field": "created", + "sort_reverse": true, + "filter_rules": [ + { + "rule_type": 6, + "value": "39" + } + ] + } + ] +} diff --git a/src-ui/cypress/fixtures/tasks/tasks.json b/src-ui/cypress/fixtures/tasks/tasks.json index eeccfe424..25e4d0748 100644 --- a/src-ui/cypress/fixtures/tasks/tasks.json +++ b/src-ui/cypress/fixtures/tasks/tasks.json @@ -5,23 +5,11 @@ "result": "sample 2.pdf: Not consuming sample 2.pdf: It is a duplicate. : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ngx.nosync-udqDZzaE/lib/python3.8/site-packages/django_q/cluster.py\", line 432, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/paperless-ngx/src/documents/tasks.py\", line 316, in consume_file\n document = Consumer().try_consume_file(\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 218, in try_consume_file\n self.pre_check_duplicate()\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 113, in pre_check_duplicate\n self._fail(\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 84, in _fail\n raise ConsumerError(f\"{self.filename}: {log_message or message}\")\ndocuments.consumer.ConsumerError: sample 2.pdf: Not consuming sample 2.pdf: It is a duplicate.\n", "status": "FAILURE", "task_id": "d8ddbe298a42427d82553206ddf0bc94", - "name": "sample 2.pdf", - "created": "2022-05-26T23:17:38.333474-07:00", + "task_file_name": "sample 2.pdf", + "date_created": "2022-05-26T23:17:38.333474-07:00", + "date_done": null, "acknowledged": false, - "attempted_task": { - "id": "d8ddbe298a42427d82553206ddf0bc94", - "name": "sample 2.pdf", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtanJxNGs1aHOUhZQu", - "kwargs": "gAWVzQAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwMc2FtcGxlIDIucGRmlIwOb3ZlcnJpZGVfdGl0bGWUTowZb3ZlcnJpZGVfY29ycmVzcG9uZGVudF9pZJROjBlvdmVycmlkZV9kb2N1bWVudF90eXBlX2lklE6MEG92ZXJyaWRlX3RhZ19pZHOUTowHdGFza19pZJSMJDcyMGExYjI5LWI2OTYtNDY3My05Y2ZmLTJkY2ZiZWNmNWViMpSMEG92ZXJyaWRlX2NyZWF0ZWSUTnUu", - "result": "gAWVMQQAAAAAAABYKgQAAHNhbXBsZSAyLnBkZjogTm90IGNvbnN1bWluZyBzYW1wbGUgMi5wZGY6IEl0IGlzIGEgZHVwbGljYXRlLiA6IFRyYWNlYmFjayAobW9zdCByZWNlbnQgY2FsbCBsYXN0KToKICBGaWxlICIvVXNlcnMvbW9vbmVyLy5sb2NhbC9zaGFyZS92aXJ0dWFsZW52cy9wYXBlcmxlc3Mtbmd4Lm5vc3luYy11ZHFEWnphRS9saWIvcHl0aG9uMy44L3NpdGUtcGFja2FnZXMvZGphbmdvX3EvY2x1c3Rlci5weSIsIGxpbmUgNDMyLCBpbiB3b3JrZXIKICAgIHJlcyA9IGYoKnRhc2tbImFyZ3MiXSwgKip0YXNrWyJrd2FyZ3MiXSkKICBGaWxlICIvVXNlcnMvbW9vbmVyL0RvY3VtZW50cy9Xb3JrL0Rldi5ub3N5bmMvQ29udHJpYnV0aW9ucy9wYXBlcmxlc3Mtbmd4L3NyYy9kb2N1bWVudHMvdGFza3MucHkiLCBsaW5lIDMxNiwgaW4gY29uc3VtZV9maWxlCiAgICBkb2N1bWVudCA9IENvbnN1bWVyKCkudHJ5X2NvbnN1bWVfZmlsZSgKICBGaWxlICIvVXNlcnMvbW9vbmVyL0RvY3VtZW50cy9Xb3JrL0Rldi5ub3N5bmMvQ29udHJpYnV0aW9ucy9wYXBlcmxlc3Mtbmd4L3NyYy9kb2N1bWVudHMvY29uc3VtZXIucHkiLCBsaW5lIDIxOCwgaW4gdHJ5X2NvbnN1bWVfZmlsZQogICAgc2VsZi5wcmVfY2hlY2tfZHVwbGljYXRlKCkKICBGaWxlICIvVXNlcnMvbW9vbmVyL0RvY3VtZW50cy9Xb3JrL0Rldi5ub3N5bmMvQ29udHJpYnV0aW9ucy9wYXBlcmxlc3Mtbmd4L3NyYy9kb2N1bWVudHMvY29uc3VtZXIucHkiLCBsaW5lIDExMywgaW4gcHJlX2NoZWNrX2R1cGxpY2F0ZQogICAgc2VsZi5fZmFpbCgKICBGaWxlICIvVXNlcnMvbW9vbmVyL0RvY3VtZW50cy9Xb3JrL0Rldi5ub3N5bmMvQ29udHJpYnV0aW9ucy9wYXBlcmxlc3Mtbmd4L3NyYy9kb2N1bWVudHMvY29uc3VtZXIucHkiLCBsaW5lIDg0LCBpbiBfZmFpbAogICAgcmFpc2UgQ29uc3VtZXJFcnJvcihmIntzZWxmLmZpbGVuYW1lfToge2xvZ19tZXNzYWdlIG9yIG1lc3NhZ2V9IikKZG9jdW1lbnRzLmNvbnN1bWVyLkNvbnN1bWVyRXJyb3I6IHNhbXBsZSAyLnBkZjogTm90IGNvbnN1bWluZyBzYW1wbGUgMi5wZGY6IEl0IGlzIGEgZHVwbGljYXRlLgqULg==", - "group": null, - "started": "2022-05-26T23:17:37.702432-07:00", - "stopped": "2022-05-26T23:17:38.313306-07:00", - "success": false, - "attempt_count": 1 - } + "related_document": null }, { "id": 132, @@ -29,23 +17,10 @@ "result": " : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 131, in get_version\n env=env,\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 68, in run\n proc = subprocess_run(args, env=env, **kwargs)\n File \"/Users/admin/opt/anaconda3/envs/paperless-ng/lib/python3.6/subprocess.py\", line 423, in run\n with Popen(*popenargs, **kwargs) as process:\n File \"/Users/admin/opt/anaconda3/envs/paperless-ng/lib/python3.6/subprocess.py\", line 729, in __init__\n restore_signals, start_new_session)\n File \"/Users/admin/opt/anaconda3/envs/paperless-ng/lib/python3.6/subprocess.py\", line 1364, in _execute_child\n raise child_exception_type(errno_num, err_msg, err_filename)\nFileNotFoundError: [Errno 2] No such file or directory: 'unpaper': 'unpaper'\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 287, in check_external_program\n found_version = version_checker()\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/_exec/unpaper.py\", line 34, in version\n return get_version('unpaper')\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 137, in get_version\n ) from e\nocrmypdf.exceptions.MissingDependencyError: Could not find program 'unpaper' on the PATH\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/paperless_tesseract/parsers.py\", line 176, in parse\n ocrmypdf.ocr(**ocr_args)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/api.py\", line 315, in ocr\n check_options(options, plugin_manager)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/_validation.py\", line 260, in check_options\n _check_options(options, plugin_manager, ocr_engine_languages)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/_validation.py\", line 250, in _check_options\n check_options_preprocessing(options)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/_validation.py\", line 128, in check_options_preprocessing\n required_for=['--clean, --clean-final'],\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 293, in check_external_program\n raise MissingDependencyError()\nocrmypdf.exceptions.MissingDependencyError\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 179, in try_consume_file\n document_parser.parse(self.path, mime_type, self.filename)\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/paperless_tesseract/parsers.py\", line 197, in parse\n raise ParseError(e)\ndocuments.parsers.ParseError\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/django_q/cluster.py\", line 436, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/tasks.py\", line 73, in consume_file\n override_tag_ids=override_tag_ids)\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 196, in try_consume_file\n raise ConsumerError(e)\ndocuments.consumer.ConsumerError\n", "status": "FAILURE", "task_id": "4c554075552c4cc985abd76e6f274c90", - "name": "pdf-sample 10.24.48 PM.pdf", - "created": "2022-05-26T14:26:07.846365-07:00", - "acknowledged": null, - "attempted_task": { - "id": "4c554075552c4cc985abd76e6f274c90", - "name": "pdf-sample 10.24.48 PM.pdf", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVKwAAAAAAAACMJS4uL2NvbnN1bWUvcGRmLXNhbXBsZSAxMC4yNC40OCBQTS5wZGaUhZQu", - "kwargs": "gAWVGAAAAAAAAAB9lIwQb3ZlcnJpZGVfdGFnX2lkc5ROcy4=", - "result": "gAWVzA8AAAAAAABYxQ8AACA6IFRyYWNlYmFjayAobW9zdCByZWNlbnQgY2FsbCBsYXN0KToKICBGaWxlICIvVXNlcnMvbW9vbmVyLy5sb2NhbC9zaGFyZS92aXJ0dWFsZW52cy9wYXBlcmxlc3MtbmctNzZCdUpsRUkvbGliL3B5dGhvbjMuNi9zaXRlLXBhY2thZ2VzL29jcm15cGRmL3N1YnByb2Nlc3MucHkiLCBsaW5lIDEzMSwgaW4gZ2V0X3ZlcnNpb24KICAgIGVudj1lbnYsCiAgRmlsZSAiL1VzZXJzL21vb25lci8ubG9jYWwvc2hhcmUvdmlydHVhbGVudnMvcGFwZXJsZXNzLW5nLTc2QnVKbEVJL2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9vY3JteXBkZi9zdWJwcm9jZXNzLnB5IiwgbGluZSA2OCwgaW4gcnVuCiAgICBwcm9jID0gc3VicHJvY2Vzc19ydW4oYXJncywgZW52PWVudiwgKiprd2FyZ3MpCiAgRmlsZSAiL1VzZXJzL21vb25lci9vcHQvYW5hY29uZGEzL2VudnMvcGFwZXJsZXNzLW5nL2xpYi9weXRob24zLjYvc3VicHJvY2Vzcy5weSIsIGxpbmUgNDIzLCBpbiBydW4KICAgIHdpdGggUG9wZW4oKnBvcGVuYXJncywgKiprd2FyZ3MpIGFzIHByb2Nlc3M6CiAgRmlsZSAiL1VzZXJzL21vb25lci9vcHQvYW5hY29uZGEzL2VudnMvcGFwZXJsZXNzLW5nL2xpYi9weXRob24zLjYvc3VicHJvY2Vzcy5weSIsIGxpbmUgNzI5LCBpbiBfX2luaXRfXwogICAgcmVzdG9yZV9zaWduYWxzLCBzdGFydF9uZXdfc2Vzc2lvbikKICBGaWxlICIvVXNlcnMvbW9vbmVyL29wdC9hbmFjb25kYTMvZW52cy9wYXBlcmxlc3MtbmcvbGliL3B5dGhvbjMuNi9zdWJwcm9jZXNzLnB5IiwgbGluZSAxMzY0LCBpbiBfZXhlY3V0ZV9jaGlsZAogICAgcmFpc2UgY2hpbGRfZXhjZXB0aW9uX3R5cGUoZXJybm9fbnVtLCBlcnJfbXNnLCBlcnJfZmlsZW5hbWUpCkZpbGVOb3RGb3VuZEVycm9yOiBbRXJybm8gMl0gTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJ3VucGFwZXInOiAndW5wYXBlcicKClRoZSBhYm92ZSBleGNlcHRpb24gd2FzIHRoZSBkaXJlY3QgY2F1c2Ugb2YgdGhlIGZvbGxvd2luZyBleGNlcHRpb246CgpUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6CiAgRmlsZSAiL1VzZXJzL21vb25lci8ubG9jYWwvc2hhcmUvdmlydHVhbGVudnMvcGFwZXJsZXNzLW5nLTc2QnVKbEVJL2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9vY3JteXBkZi9zdWJwcm9jZXNzLnB5IiwgbGluZSAyODcsIGluIGNoZWNrX2V4dGVybmFsX3Byb2dyYW0KICAgIGZvdW5kX3ZlcnNpb24gPSB2ZXJzaW9uX2NoZWNrZXIoKQogIEZpbGUgIi9Vc2Vycy9tb29uZXIvLmxvY2FsL3NoYXJlL3ZpcnR1YWxlbnZzL3BhcGVybGVzcy1uZy03NkJ1SmxFSS9saWIvcHl0aG9uMy42L3NpdGUtcGFja2FnZXMvb2NybXlwZGYvX2V4ZWMvdW5wYXBlci5weSIsIGxpbmUgMzQsIGluIHZlcnNpb24KICAgIHJldHVybiBnZXRfdmVyc2lvbigndW5wYXBlcicpCiAgRmlsZSAiL1VzZXJzL21vb25lci8ubG9jYWwvc2hhcmUvdmlydHVhbGVudnMvcGFwZXJsZXNzLW5nLTc2QnVKbEVJL2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9vY3JteXBkZi9zdWJwcm9jZXNzLnB5IiwgbGluZSAxMzcsIGluIGdldF92ZXJzaW9uCiAgICApIGZyb20gZQpvY3JteXBkZi5leGNlcHRpb25zLk1pc3NpbmdEZXBlbmRlbmN5RXJyb3I6IENvdWxkIG5vdCBmaW5kIHByb2dyYW0gJ3VucGFwZXInIG9uIHRoZSBQQVRICgpEdXJpbmcgaGFuZGxpbmcgb2YgdGhlIGFib3ZlIGV4Y2VwdGlvbiwgYW5vdGhlciBleGNlcHRpb24gb2NjdXJyZWQ6CgpUcmFjZWJhY2sgKG1vc3QgcmVjZW50IGNhbGwgbGFzdCk6CiAgRmlsZSAiL1VzZXJzL21vb25lci9Eb2N1bWVudHMvV29yay9Db250cmlidXRpb25zL3BhcGVybGVzcy1uZy9zcmMvcGFwZXJsZXNzX3Rlc3NlcmFjdC9wYXJzZXJzLnB5IiwgbGluZSAxNzYsIGluIHBhcnNlCiAgICBvY3JteXBkZi5vY3IoKipvY3JfYXJncykKICBGaWxlICIvVXNlcnMvbW9vbmVyLy5sb2NhbC9zaGFyZS92aXJ0dWFsZW52cy9wYXBlcmxlc3MtbmctNzZCdUpsRUkvbGliL3B5dGhvbjMuNi9zaXRlLXBhY2thZ2VzL29jcm15cGRmL2FwaS5weSIsIGxpbmUgMzE1LCBpbiBvY3IKICAgIGNoZWNrX29wdGlvbnMob3B0aW9ucywgcGx1Z2luX21hbmFnZXIpCiAgRmlsZSAiL1VzZXJzL21vb25lci8ubG9jYWwvc2hhcmUvdmlydHVhbGVudnMvcGFwZXJsZXNzLW5nLTc2QnVKbEVJL2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9vY3JteXBkZi9fdmFsaWRhdGlvbi5weSIsIGxpbmUgMjYwLCBpbiBjaGVja19vcHRpb25zCiAgICBfY2hlY2tfb3B0aW9ucyhvcHRpb25zLCBwbHVnaW5fbWFuYWdlciwgb2NyX2VuZ2luZV9sYW5ndWFnZXMpCiAgRmlsZSAiL1VzZXJzL21vb25lci8ubG9jYWwvc2hhcmUvdmlydHVhbGVudnMvcGFwZXJsZXNzLW5nLTc2QnVKbEVJL2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9vY3JteXBkZi9fdmFsaWRhdGlvbi5weSIsIGxpbmUgMjUwLCBpbiBfY2hlY2tfb3B0aW9ucwogICAgY2hlY2tfb3B0aW9uc19wcmVwcm9jZXNzaW5nKG9wdGlvbnMpCiAgRmlsZSAiL1VzZXJzL21vb25lci8ubG9jYWwvc2hhcmUvdmlydHVhbGVudnMvcGFwZXJsZXNzLW5nLTc2QnVKbEVJL2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9vY3JteXBkZi9fdmFsaWRhdGlvbi5weSIsIGxpbmUgMTI4LCBpbiBjaGVja19vcHRpb25zX3ByZXByb2Nlc3NpbmcKICAgIHJlcXVpcmVkX2Zvcj1bJy0tY2xlYW4sIC0tY2xlYW4tZmluYWwnXSwKICBGaWxlICIvVXNlcnMvbW9vbmVyLy5sb2NhbC9zaGFyZS92aXJ0dWFsZW52cy9wYXBlcmxlc3MtbmctNzZCdUpsRUkvbGliL3B5dGhvbjMuNi9zaXRlLXBhY2thZ2VzL29jcm15cGRmL3N1YnByb2Nlc3MucHkiLCBsaW5lIDI5MywgaW4gY2hlY2tfZXh0ZXJuYWxfcHJvZ3JhbQogICAgcmFpc2UgTWlzc2luZ0RlcGVuZGVuY3lFcnJvcigpCm9jcm15cGRmLmV4Y2VwdGlvbnMuTWlzc2luZ0RlcGVuZGVuY3lFcnJvcgoKRHVyaW5nIGhhbmRsaW5nIG9mIHRoZSBhYm92ZSBleGNlcHRpb24sIGFub3RoZXIgZXhjZXB0aW9uIG9jY3VycmVkOgoKVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOgogIEZpbGUgIi9Vc2Vycy9tb29uZXIvRG9jdW1lbnRzL1dvcmsvQ29udHJpYnV0aW9ucy9wYXBlcmxlc3Mtbmcvc3JjL2RvY3VtZW50cy9jb25zdW1lci5weSIsIGxpbmUgMTc5LCBpbiB0cnlfY29uc3VtZV9maWxlCiAgICBkb2N1bWVudF9wYXJzZXIucGFyc2Uoc2VsZi5wYXRoLCBtaW1lX3R5cGUsIHNlbGYuZmlsZW5hbWUpCiAgRmlsZSAiL1VzZXJzL21vb25lci9Eb2N1bWVudHMvV29yay9Db250cmlidXRpb25zL3BhcGVybGVzcy1uZy9zcmMvcGFwZXJsZXNzX3Rlc3NlcmFjdC9wYXJzZXJzLnB5IiwgbGluZSAxOTcsIGluIHBhcnNlCiAgICByYWlzZSBQYXJzZUVycm9yKGUpCmRvY3VtZW50cy5wYXJzZXJzLlBhcnNlRXJyb3IKCkR1cmluZyBoYW5kbGluZyBvZiB0aGUgYWJvdmUgZXhjZXB0aW9uLCBhbm90aGVyIGV4Y2VwdGlvbiBvY2N1cnJlZDoKClRyYWNlYmFjayAobW9zdCByZWNlbnQgY2FsbCBsYXN0KToKICBGaWxlICIvVXNlcnMvbW9vbmVyLy5sb2NhbC9zaGFyZS92aXJ0dWFsZW52cy9wYXBlcmxlc3MtbmctNzZCdUpsRUkvbGliL3B5dGhvbjMuNi9zaXRlLXBhY2thZ2VzL2RqYW5nb19xL2NsdXN0ZXIucHkiLCBsaW5lIDQzNiwgaW4gd29ya2VyCiAgICByZXMgPSBmKCp0YXNrWyJhcmdzIl0sICoqdGFza1sia3dhcmdzIl0pCiAgRmlsZSAiL1VzZXJzL21vb25lci9Eb2N1bWVudHMvV29yay9Db250cmlidXRpb25zL3BhcGVybGVzcy1uZy9zcmMvZG9jdW1lbnRzL3Rhc2tzLnB5IiwgbGluZSA3MywgaW4gY29uc3VtZV9maWxlCiAgICBvdmVycmlkZV90YWdfaWRzPW92ZXJyaWRlX3RhZ19pZHMpCiAgRmlsZSAiL1VzZXJzL21vb25lci9Eb2N1bWVudHMvV29yay9Db250cmlidXRpb25zL3BhcGVybGVzcy1uZy9zcmMvZG9jdW1lbnRzL2NvbnN1bWVyLnB5IiwgbGluZSAxOTYsIGluIHRyeV9jb25zdW1lX2ZpbGUKICAgIHJhaXNlIENvbnN1bWVyRXJyb3IoZSkKZG9jdW1lbnRzLmNvbnN1bWVyLkNvbnN1bWVyRXJyb3IKlC4=", - "group": null, - "started": "2021-01-20T10:47:34.535478-08:00", - "stopped": "2021-01-20T10:49:55.568010-08:00", - "success": false, - "attempt_count": 1 - } + "task_file_name": "pdf-sample 10.24.48 PM.pdf", + "date_created": "2022-05-26T14:26:07.846365-07:00", + "date_done": null, + "acknowledged": null }, { "id": 115, @@ -53,23 +28,10 @@ "result": "2021-01-24 2021-01-20 sample_wide_orange.pdf: Document is a duplicate : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/django_q/cluster.py\", line 436, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/tasks.py\", line 75, in consume_file\n task_id=task_id\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 168, in try_consume_file\n self.pre_check_duplicate()\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 85, in pre_check_duplicate\n self._fail(\"Document is a duplicate\")\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 53, in _fail\n raise ConsumerError(f\"{self.filename}: {message}\")\ndocuments.consumer.ConsumerError: 2021-01-24 2021-01-20 sample_wide_orange.pdf: Document is a duplicate\n", "status": "FAILURE", "task_id": "86494713646a4364b01da17aadca071d", - "name": "2021-01-24 2021-01-20 sample_wide_orange.pdf", - "created": "2022-05-26T14:26:07.817608-07:00", - "acknowledged": null, - "attempted_task": { - "id": "86494713646a4364b01da17aadca071d", - "name": "2021-01-24 2021-01-20 sample_wide_orange.pdf", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtcTJ6NDlnbzaUhZQu", - "kwargs": "gAWV2QAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwsMjAyMS0wMS0yNCAyMDIxLTAxLTIwIHNhbXBsZV93aWRlX29yYW5nZS5wZGaUjA5vdmVycmlkZV90aXRsZZROjBlvdmVycmlkZV9jb3JyZXNwb25kZW50X2lklE6MGW92ZXJyaWRlX2RvY3VtZW50X3R5cGVfaWSUTowQb3ZlcnJpZGVfdGFnX2lkc5ROjAd0YXNrX2lklIwkN2MwZTY1MmQtZDhkYy00OWU4LWI1ZmUtOGM3ZTkyZDlmOTI0lHUu", - "result": "gAWV/AMAAAAAAABY9QMAADIwMjEtMDEtMjQgMjAyMS0wMS0yMCBzYW1wbGVfd2lkZV9vcmFuZ2UucGRmOiBEb2N1bWVudCBpcyBhIGR1cGxpY2F0ZSA6IFRyYWNlYmFjayAobW9zdCByZWNlbnQgY2FsbCBsYXN0KToKICBGaWxlICIvVXNlcnMvbW9vbmVyLy5sb2NhbC9zaGFyZS92aXJ0dWFsZW52cy9wYXBlcmxlc3MtbmctNzZCdUpsRUkvbGliL3B5dGhvbjMuNi9zaXRlLXBhY2thZ2VzL2RqYW5nb19xL2NsdXN0ZXIucHkiLCBsaW5lIDQzNiwgaW4gd29ya2VyCiAgICByZXMgPSBmKCp0YXNrWyJhcmdzIl0sICoqdGFza1sia3dhcmdzIl0pCiAgRmlsZSAiL1VzZXJzL21vb25lci9Eb2N1bWVudHMvV29yay9Db250cmlidXRpb25zL3BhcGVybGVzcy1uZy9zcmMvZG9jdW1lbnRzL3Rhc2tzLnB5IiwgbGluZSA3NSwgaW4gY29uc3VtZV9maWxlCiAgICB0YXNrX2lkPXRhc2tfaWQKICBGaWxlICIvVXNlcnMvbW9vbmVyL0RvY3VtZW50cy9Xb3JrL0NvbnRyaWJ1dGlvbnMvcGFwZXJsZXNzLW5nL3NyYy9kb2N1bWVudHMvY29uc3VtZXIucHkiLCBsaW5lIDE2OCwgaW4gdHJ5X2NvbnN1bWVfZmlsZQogICAgc2VsZi5wcmVfY2hlY2tfZHVwbGljYXRlKCkKICBGaWxlICIvVXNlcnMvbW9vbmVyL0RvY3VtZW50cy9Xb3JrL0NvbnRyaWJ1dGlvbnMvcGFwZXJsZXNzLW5nL3NyYy9kb2N1bWVudHMvY29uc3VtZXIucHkiLCBsaW5lIDg1LCBpbiBwcmVfY2hlY2tfZHVwbGljYXRlCiAgICBzZWxmLl9mYWlsKCJEb2N1bWVudCBpcyBhIGR1cGxpY2F0ZSIpCiAgRmlsZSAiL1VzZXJzL21vb25lci9Eb2N1bWVudHMvV29yay9Db250cmlidXRpb25zL3BhcGVybGVzcy1uZy9zcmMvZG9jdW1lbnRzL2NvbnN1bWVyLnB5IiwgbGluZSA1MywgaW4gX2ZhaWwKICAgIHJhaXNlIENvbnN1bWVyRXJyb3IoZiJ7c2VsZi5maWxlbmFtZX06IHttZXNzYWdlfSIpCmRvY3VtZW50cy5jb25zdW1lci5Db25zdW1lckVycm9yOiAyMDIxLTAxLTI0IDIwMjEtMDEtMjAgc2FtcGxlX3dpZGVfb3JhbmdlLnBkZjogRG9jdW1lbnQgaXMgYSBkdXBsaWNhdGUKlC4=", - "group": null, - "started": "2021-01-26T00:21:05.379583-08:00", - "stopped": "2021-01-26T00:21:06.449626-08:00", - "success": false, - "attempt_count": 1 - } + "task_file_name": "2021-01-24 2021-01-20 sample_wide_orange.pdf", + "date_created": "2022-05-26T14:26:07.817608-07:00", + "date_done": null, + "acknowledged": null }, { "id": 85, @@ -77,23 +39,10 @@ "result": "cannot open resource : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/django_q/cluster.py\", line 436, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/tasks.py\", line 81, in consume_file\n task_id=task_id\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 244, in try_consume_file\n self.path, mime_type, self.filename)\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/parsers.py\", line 302, in get_optimised_thumbnail\n thumbnail = self.get_thumbnail(document_path, mime_type, file_name)\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/paperless_text/parsers.py\", line 29, in get_thumbnail\n layout_engine=ImageFont.LAYOUT_BASIC)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/PIL/ImageFont.py\", line 852, in truetype\n return freetype(font)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/PIL/ImageFont.py\", line 849, in freetype\n return FreeTypeFont(font, size, index, encoding, layout_engine)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/PIL/ImageFont.py\", line 210, in __init__\n font, size, index, encoding, layout_engine=layout_engine\nOSError: cannot open resource\n", "status": "FAILURE", "task_id": "abca803fa46342e1ac81f3d3f2080e79", - "name": "simple.txt", - "created": "2022-05-26T14:26:07.771541-07:00", - "acknowledged": null, - "attempted_task": { - "id": "abca803fa46342e1ac81f3d3f2080e79", - "name": "simple.txt", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtd2RhbnB5NnGUhZQu", - "kwargs": "gAWVtwAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwKc2ltcGxlLnR4dJSMDm92ZXJyaWRlX3RpdGxllE6MGW92ZXJyaWRlX2NvcnJlc3BvbmRlbnRfaWSUTowZb3ZlcnJpZGVfZG9jdW1lbnRfdHlwZV9pZJROjBBvdmVycmlkZV90YWdfaWRzlE6MB3Rhc2tfaWSUjCQ3ZGE0OTU4ZC0zM2UwLTQ1OGMtYTE0ZC1kMmU0NmE0NWY4Y2SUdS4=", - "result": "gAWV5QUAAAAAAABY3gUAAGNhbm5vdCBvcGVuIHJlc291cmNlIDogVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOgogIEZpbGUgIi9Vc2Vycy9tb29uZXIvLmxvY2FsL3NoYXJlL3ZpcnR1YWxlbnZzL3BhcGVybGVzcy1uZy03NkJ1SmxFSS9saWIvcHl0aG9uMy42L3NpdGUtcGFja2FnZXMvZGphbmdvX3EvY2x1c3Rlci5weSIsIGxpbmUgNDM2LCBpbiB3b3JrZXIKICAgIHJlcyA9IGYoKnRhc2tbImFyZ3MiXSwgKip0YXNrWyJrd2FyZ3MiXSkKICBGaWxlICIvVXNlcnMvbW9vbmVyL0RvY3VtZW50cy9Xb3JrL0NvbnRyaWJ1dGlvbnMvcGFwZXJsZXNzLW5nL3NyYy9kb2N1bWVudHMvdGFza3MucHkiLCBsaW5lIDgxLCBpbiBjb25zdW1lX2ZpbGUKICAgIHRhc2tfaWQ9dGFza19pZAogIEZpbGUgIi9Vc2Vycy9tb29uZXIvRG9jdW1lbnRzL1dvcmsvQ29udHJpYnV0aW9ucy9wYXBlcmxlc3Mtbmcvc3JjL2RvY3VtZW50cy9jb25zdW1lci5weSIsIGxpbmUgMjQ0LCBpbiB0cnlfY29uc3VtZV9maWxlCiAgICBzZWxmLnBhdGgsIG1pbWVfdHlwZSwgc2VsZi5maWxlbmFtZSkKICBGaWxlICIvVXNlcnMvbW9vbmVyL0RvY3VtZW50cy9Xb3JrL0NvbnRyaWJ1dGlvbnMvcGFwZXJsZXNzLW5nL3NyYy9kb2N1bWVudHMvcGFyc2Vycy5weSIsIGxpbmUgMzAyLCBpbiBnZXRfb3B0aW1pc2VkX3RodW1ibmFpbAogICAgdGh1bWJuYWlsID0gc2VsZi5nZXRfdGh1bWJuYWlsKGRvY3VtZW50X3BhdGgsIG1pbWVfdHlwZSwgZmlsZV9uYW1lKQogIEZpbGUgIi9Vc2Vycy9tb29uZXIvRG9jdW1lbnRzL1dvcmsvQ29udHJpYnV0aW9ucy9wYXBlcmxlc3Mtbmcvc3JjL3BhcGVybGVzc190ZXh0L3BhcnNlcnMucHkiLCBsaW5lIDI5LCBpbiBnZXRfdGh1bWJuYWlsCiAgICBsYXlvdXRfZW5naW5lPUltYWdlRm9udC5MQVlPVVRfQkFTSUMpCiAgRmlsZSAiL1VzZXJzL21vb25lci8ubG9jYWwvc2hhcmUvdmlydHVhbGVudnMvcGFwZXJsZXNzLW5nLTc2QnVKbEVJL2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9QSUwvSW1hZ2VGb250LnB5IiwgbGluZSA4NTIsIGluIHRydWV0eXBlCiAgICByZXR1cm4gZnJlZXR5cGUoZm9udCkKICBGaWxlICIvVXNlcnMvbW9vbmVyLy5sb2NhbC9zaGFyZS92aXJ0dWFsZW52cy9wYXBlcmxlc3MtbmctNzZCdUpsRUkvbGliL3B5dGhvbjMuNi9zaXRlLXBhY2thZ2VzL1BJTC9JbWFnZUZvbnQucHkiLCBsaW5lIDg0OSwgaW4gZnJlZXR5cGUKICAgIHJldHVybiBGcmVlVHlwZUZvbnQoZm9udCwgc2l6ZSwgaW5kZXgsIGVuY29kaW5nLCBsYXlvdXRfZW5naW5lKQogIEZpbGUgIi9Vc2Vycy9tb29uZXIvLmxvY2FsL3NoYXJlL3ZpcnR1YWxlbnZzL3BhcGVybGVzcy1uZy03NkJ1SmxFSS9saWIvcHl0aG9uMy42L3NpdGUtcGFja2FnZXMvUElML0ltYWdlRm9udC5weSIsIGxpbmUgMjEwLCBpbiBfX2luaXRfXwogICAgZm9udCwgc2l6ZSwgaW5kZXgsIGVuY29kaW5nLCBsYXlvdXRfZW5naW5lPWxheW91dF9lbmdpbmUKT1NFcnJvcjogY2Fubm90IG9wZW4gcmVzb3VyY2UKlC4=", - "group": null, - "started": "2021-03-06T14:23:56.974715-08:00", - "stopped": "2021-03-06T14:24:28.011772-08:00", - "success": false, - "attempt_count": 1 - } + "task_file_name": "simple.txt", + "date_created": "2022-05-26T14:26:07.771541-07:00", + "date_done": null, + "acknowledged": null }, { "id": 41, @@ -101,23 +50,10 @@ "result": "commands.txt: Not consuming commands.txt: It is a duplicate. : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ngx.nosync-udqDZzaE/lib/python3.8/site-packages/django_q/cluster.py\", line 432, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/paperless-ngx/src/documents/tasks.py\", line 70, in consume_file\n document = Consumer().try_consume_file(\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 199, in try_consume_file\n self.pre_check_duplicate()\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 97, in pre_check_duplicate\n self._fail(\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 69, in _fail\n raise ConsumerError(f\"{self.filename}: {log_message or message}\")\ndocuments.consumer.ConsumerError: commands.txt: Not consuming commands.txt: It is a duplicate.\n", "status": "FAILURE", "task_id": "0af67672e8e14404b060d4cf8f69313d", - "name": "commands.txt", - "created": "2022-05-26T14:26:07.704247-07:00", - "acknowledged": null, - "attempted_task": { - "id": "0af67672e8e14404b060d4cf8f69313d", - "name": "commands.txt", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtZ3h4YjNxODaUhZQu", - "kwargs": "gAWVuQAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwMY29tbWFuZHMudHh0lIwOb3ZlcnJpZGVfdGl0bGWUTowZb3ZlcnJpZGVfY29ycmVzcG9uZGVudF9pZJROjBlvdmVycmlkZV9kb2N1bWVudF90eXBlX2lklE6MEG92ZXJyaWRlX3RhZ19pZHOUTowHdGFza19pZJSMJDRkMjhmMmJiLTJkMzAtNGQzNi1iNjM5LWU2YzQ5OTU3OGVlY5R1Lg==", - "result": "gAWVLwQAAAAAAABYKAQAAGNvbW1hbmRzLnR4dDogTm90IGNvbnN1bWluZyBjb21tYW5kcy50eHQ6IEl0IGlzIGEgZHVwbGljYXRlLiA6IFRyYWNlYmFjayAobW9zdCByZWNlbnQgY2FsbCBsYXN0KToKICBGaWxlICIvVXNlcnMvbW9vbmVyLy5sb2NhbC9zaGFyZS92aXJ0dWFsZW52cy9wYXBlcmxlc3Mtbmd4Lm5vc3luYy11ZHFEWnphRS9saWIvcHl0aG9uMy44L3NpdGUtcGFja2FnZXMvZGphbmdvX3EvY2x1c3Rlci5weSIsIGxpbmUgNDMyLCBpbiB3b3JrZXIKICAgIHJlcyA9IGYoKnRhc2tbImFyZ3MiXSwgKip0YXNrWyJrd2FyZ3MiXSkKICBGaWxlICIvVXNlcnMvbW9vbmVyL0RvY3VtZW50cy9Xb3JrL0Rldi5ub3N5bmMvQ29udHJpYnV0aW9ucy9wYXBlcmxlc3Mtbmd4L3NyYy9kb2N1bWVudHMvdGFza3MucHkiLCBsaW5lIDcwLCBpbiBjb25zdW1lX2ZpbGUKICAgIGRvY3VtZW50ID0gQ29uc3VtZXIoKS50cnlfY29uc3VtZV9maWxlKAogIEZpbGUgIi9Vc2Vycy9tb29uZXIvRG9jdW1lbnRzL1dvcmsvRGV2Lm5vc3luYy9Db250cmlidXRpb25zL3BhcGVybGVzcy1uZ3gvc3JjL2RvY3VtZW50cy9jb25zdW1lci5weSIsIGxpbmUgMTk5LCBpbiB0cnlfY29uc3VtZV9maWxlCiAgICBzZWxmLnByZV9jaGVja19kdXBsaWNhdGUoKQogIEZpbGUgIi9Vc2Vycy9tb29uZXIvRG9jdW1lbnRzL1dvcmsvRGV2Lm5vc3luYy9Db250cmlidXRpb25zL3BhcGVybGVzcy1uZ3gvc3JjL2RvY3VtZW50cy9jb25zdW1lci5weSIsIGxpbmUgOTcsIGluIHByZV9jaGVja19kdXBsaWNhdGUKICAgIHNlbGYuX2ZhaWwoCiAgRmlsZSAiL1VzZXJzL21vb25lci9Eb2N1bWVudHMvV29yay9EZXYubm9zeW5jL0NvbnRyaWJ1dGlvbnMvcGFwZXJsZXNzLW5neC9zcmMvZG9jdW1lbnRzL2NvbnN1bWVyLnB5IiwgbGluZSA2OSwgaW4gX2ZhaWwKICAgIHJhaXNlIENvbnN1bWVyRXJyb3IoZiJ7c2VsZi5maWxlbmFtZX06IHtsb2dfbWVzc2FnZSBvciBtZXNzYWdlfSIpCmRvY3VtZW50cy5jb25zdW1lci5Db25zdW1lckVycm9yOiBjb21tYW5kcy50eHQ6IE5vdCBjb25zdW1pbmcgY29tbWFuZHMudHh0OiBJdCBpcyBhIGR1cGxpY2F0ZS4KlC4=", - "group": null, - "started": "2022-03-10T22:26:32.548772-08:00", - "stopped": "2022-03-10T22:26:32.879916-08:00", - "success": false, - "attempt_count": 1 - } + "task_file_name": "commands.txt", + "date_created": "2022-05-26T14:26:07.704247-07:00", + "date_done": null, + "acknowledged": null }, { "id": 10, @@ -125,23 +61,11 @@ "result": "Success. New document id 260 created", "status": "SUCCESS", "task_id": "b7629a0f41bd40c7a3ea4680341321b5", - "name": "2022-03-24+Sonstige+ScanPC2022-03-24_081058.pdf", - "created": "2022-05-26T14:26:07.670577-07:00", + "task_file_name": "2022-03-24+Sonstige+ScanPC2022-03-24_081058.pdf", + "date_created": "2022-05-26T14:26:07.670577-07:00", + "date_done": "2022-05-26T14:26:07.670577-07:00", "acknowledged": false, - "attempted_task": { - "id": "b7629a0f41bd40c7a3ea4680341321b5", - "name": "2022-03-24+Sonstige+ScanPC2022-03-24_081058.pdf", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtc25mOW11ZW+UhZQu", - "kwargs": "gAWV3AAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwvMjAyMi0wMy0yNCtTb25zdGlnZStTY2FuUEMyMDIyLTAzLTI0XzA4MTA1OC5wZGaUjA5vdmVycmlkZV90aXRsZZROjBlvdmVycmlkZV9jb3JyZXNwb25kZW50X2lklE6MGW92ZXJyaWRlX2RvY3VtZW50X3R5cGVfaWSUTowQb3ZlcnJpZGVfdGFnX2lkc5ROjAd0YXNrX2lklIwkNTdmMmQwMGItY2Q0Ny00YzQ3LTlmOTctODFlOTllMTJhMjMylHUu", - "result": "gAWVKAAAAAAAAACMJFN1Y2Nlc3MuIE5ldyBkb2N1bWVudCBpZCAyNjAgY3JlYXRlZJQu", - "group": null, - "started": "2022-03-24T08:19:32.117861-07:00", - "stopped": "2022-03-24T08:20:10.239201-07:00", - "success": true, - "attempt_count": 1 - } + "related_document": 260 }, { "id": 9, @@ -149,23 +73,11 @@ "result": "Success. New document id 261 created", "status": "SUCCESS", "task_id": "02e276a86a424ccfb83309df5d8594be", - "name": "2sample-pdf-with-images.pdf", - "created": "2022-05-26T14:26:07.668987-07:00", + "task_file_name": "2sample-pdf-with-images.pdf", + "date_created": "2022-05-26T14:26:07.668987-07:00", + "date_done": "2022-05-26T14:26:07.668987-07:00", "acknowledged": false, - "attempted_task": { - "id": "02e276a86a424ccfb83309df5d8594be", - "name": "2sample-pdf-with-images.pdf", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtaXJ3cjZzOGeUhZQu", - "kwargs": "gAWVyAAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwbMnNhbXBsZS1wZGYtd2l0aC1pbWFnZXMucGRmlIwOb3ZlcnJpZGVfdGl0bGWUTowZb3ZlcnJpZGVfY29ycmVzcG9uZGVudF9pZJROjBlvdmVycmlkZV9kb2N1bWVudF90eXBlX2lklE6MEG92ZXJyaWRlX3RhZ19pZHOUTowHdGFza19pZJSMJDFlYTczMjhhLTk3MjctNDJiMC1iMTEyLTAzZjU3MzQ2MmRiNpR1Lg==", - "result": "gAWVKAAAAAAAAACMJFN1Y2Nlc3MuIE5ldyBkb2N1bWVudCBpZCAyNjEgY3JlYXRlZJQu", - "group": null, - "started": "2022-03-28T23:12:41.286318-07:00", - "stopped": "2022-03-28T23:13:00.523505-07:00", - "success": true, - "attempt_count": 1 - } + "related_document": 261 }, { "id": 8, @@ -173,23 +85,11 @@ "result": "Success. New document id 262 created", "status": "SUCCESS", "task_id": "41229b8be9b445c0a523697d0f58f13e", - "name": "2sample-pdf-with-images_pw.pdf", - "created": "2022-05-26T14:26:07.667993-07:00", + "task_file_name": "2sample-pdf-with-images_pw.pdf", + "date_created": "2022-05-26T14:26:07.667993-07:00", + "date_done": "2022-05-26T14:26:07.667993-07:00", "acknowledged": false, - "attempted_task": { - "id": "41229b8be9b445c0a523697d0f58f13e", - "name": "2sample-pdf-with-images_pw.pdf", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtN2tfejA0MTGUhZQu", - "kwargs": "gAWVywAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIweMnNhbXBsZS1wZGYtd2l0aC1pbWFnZXNfcHcucGRmlIwOb3ZlcnJpZGVfdGl0bGWUTowZb3ZlcnJpZGVfY29ycmVzcG9uZGVudF9pZJROjBlvdmVycmlkZV9kb2N1bWVudF90eXBlX2lklE6MEG92ZXJyaWRlX3RhZ19pZHOUTowHdGFza19pZJSMJDk5YTgyOTc3LWU1MWUtNGJjYS04MjM4LTNkNzdhZTJhNjZmYZR1Lg==", - "result": "gAWVKAAAAAAAAACMJFN1Y2Nlc3MuIE5ldyBkb2N1bWVudCBpZCAyNjIgY3JlYXRlZJQu", - "group": null, - "started": "2022-03-28T23:43:53.171963-07:00", - "stopped": "2022-03-28T23:43:56.965257-07:00", - "success": true, - "attempt_count": 1 - } + "related_document": 262 }, { "id": 6, @@ -197,23 +97,11 @@ "result": "Success. New document id 264 created", "status": "SUCCESS", "task_id": "bbbca32d408c4619bd0b512a8327c773", - "name": "homebridge.log", - "created": "2022-05-26T14:26:07.665560-07:00", + "task_file_name": "homebridge.log", + "date_created": "2022-05-26T14:26:07.665560-07:00", + "date_done": "2022-05-26T14:26:07.665560-07:00", "acknowledged": false, - "attempted_task": { - "id": "bbbca32d408c4619bd0b512a8327c773", - "name": "homebridge.log", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQteGo4aW9zYXaUhZQu", - "kwargs": "gAWVuwAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwOaG9tZWJyaWRnZS5sb2eUjA5vdmVycmlkZV90aXRsZZROjBlvdmVycmlkZV9jb3JyZXNwb25kZW50X2lklE6MGW92ZXJyaWRlX2RvY3VtZW50X3R5cGVfaWSUTowQb3ZlcnJpZGVfdGFnX2lkc5ROjAd0YXNrX2lklIwkNzY0NzdhNWEtNzk0Ni00NWU0LWE3MDktNzQzNDg0ZDE2YTUxlHUu", - "result": "gAWVKAAAAAAAAACMJFN1Y2Nlc3MuIE5ldyBkb2N1bWVudCBpZCAyNjQgY3JlYXRlZJQu", - "group": null, - "started": "2022-03-29T22:56:16.053026-07:00", - "stopped": "2022-03-29T22:56:21.196179-07:00", - "success": true, - "attempt_count": 1 - } + "related_document": 264 }, { "id": 5, @@ -221,23 +109,11 @@ "result": "Success. New document id 265 created", "status": "SUCCESS", "task_id": "00ab285ab4bf482ab30c7d580b252ecb", - "name": "IMG_7459.PNG", - "created": "2022-05-26T14:26:07.664506-07:00", + "task_file_name": "IMG_7459.PNG", + "date_created": "2022-05-26T14:26:07.664506-07:00", + "date_done": "2022-05-26T14:26:07.664506-07:00", "acknowledged": false, - "attempted_task": { - "id": "00ab285ab4bf482ab30c7d580b252ecb", - "name": "IMG_7459.PNG", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtOGF5NDNfZjeUhZQu", - "kwargs": "gAWVuQAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwMSU1HXzc0NTkuUE5HlIwOb3ZlcnJpZGVfdGl0bGWUTowZb3ZlcnJpZGVfY29ycmVzcG9uZGVudF9pZJROjBlvdmVycmlkZV9kb2N1bWVudF90eXBlX2lklE6MEG92ZXJyaWRlX3RhZ19pZHOUTowHdGFza19pZJSMJDYxMTNhNzRlLTAwOWMtNGJhYi1hMjk1LTFmNjMwMzZmMTc4ZpR1Lg==", - "result": "gAWVKAAAAAAAAACMJFN1Y2Nlc3MuIE5ldyBkb2N1bWVudCBpZCAyNjUgY3JlYXRlZJQu", - "group": null, - "started": "2022-04-05T13:19:47.490282-07:00", - "stopped": "2022-04-05T13:21:36.782264-07:00", - "success": true, - "attempt_count": 1 - } + "related_document": 265 }, { "id": 3, @@ -245,46 +121,22 @@ "result": "Success. New document id 267 created", "status": "SUCCESS", "task_id": "289c5163cfec410db42948a0cacbeb9c", - "name": "IMG_7459.PNG", - "created": "2022-05-26T14:26:07.659661-07:00", + "task_file_name": "IMG_7459.PNG", + "date_created": "2022-05-26T14:26:07.659661-07:00", + "date_done": "2022-05-26T14:26:07.659661-07:00", "acknowledged": false, - "attempted_task": { - "id": "289c5163cfec410db42948a0cacbeb9c", - "name": "IMG_7459.PNG", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtNzRuY2p2aXGUhZQu", - "kwargs": "gAWVuQAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwMSU1HXzc0NTkuUE5HlIwOb3ZlcnJpZGVfdGl0bGWUTowZb3ZlcnJpZGVfY29ycmVzcG9uZGVudF9pZJROjBlvdmVycmlkZV9kb2N1bWVudF90eXBlX2lklE6MEG92ZXJyaWRlX3RhZ19pZHOUTowHdGFza19pZJSMJGZjZDljMmFlLWFhZmEtNGJmMC05M2Y5LWE3ZGQxYmEzYWM1NZR1Lg==", - "result": "gAWVKAAAAAAAAACMJFN1Y2Nlc3MuIE5ldyBkb2N1bWVudCBpZCAyNjcgY3JlYXRlZJQu", - "group": null, - "started": "2022-04-05T13:29:59.264441-07:00", - "stopped": "2022-04-05T13:30:28.336185-07:00", - "success": true, - "attempt_count": 1 - } + "related_document": 267 }, { "id": 1, "type": "file", - "result": "Success. New document id 268 created", - "status": "SUCCESS", + "result": null, + "status": "STARTED", "task_id": "7a4ebdb2bde04311935284027ef8ca65", - "name": "2019-08-04 DSA Questionnaire - 5-8-19.pdf", - "created": "2022-05-26T14:26:07.655276-07:00", + "task_file_name": "2019-08-04 DSA Questionnaire - 5-8-19.pdf", + "date_created": "2022-05-26T14:26:07.655276-07:00", + "date_done": null, "acknowledged": false, - "attempted_task": { - "id": "7a4ebdb2bde04311935284027ef8ca65", - "name": "2019-08-04 DSA Questionnaire - 5-8-19.pdf", - "func": "documents.tasks.consume_file", - "hook": null, - "args": "gAWVLgAAAAAAAACMKC90bXAvcGFwZXJsZXNzL3BhcGVybGVzcy11cGxvYWQtdXpscHl2NnmUhZQu", - "kwargs": "gAWV1gAAAAAAAAB9lCiMEW92ZXJyaWRlX2ZpbGVuYW1llIwpMjAxOS0wOC0wNCBEU0EgUXVlc3Rpb25uYWlyZSAtIDUtOC0xOS5wZGaUjA5vdmVycmlkZV90aXRsZZROjBlvdmVycmlkZV9jb3JyZXNwb25kZW50X2lklE6MGW92ZXJyaWRlX2RvY3VtZW50X3R5cGVfaWSUTowQb3ZlcnJpZGVfdGFnX2lkc5ROjAd0YXNrX2lklIwkY2Q3YzBhZjgtN2Q4Ni00OGM0LTliNjgtNDQwMmQ4ZDZlOTNmlHUu", - "result": "gAWVKAAAAAAAAACMJFN1Y2Nlc3MuIE5ldyBkb2N1bWVudCBpZCAyNjggY3JlYXRlZJQu", - "group": null, - "started": "2022-04-28T21:01:04.275850-07:00", - "stopped": "2022-04-28T21:01:10.136884-07:00", - "success": true, - "attempt_count": 1 - } + "related_document": null } ] diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 98ef8c968..da0fb042c 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -6,16 +6,14 @@ Close node_modules/src/alert/alert.ts - 42,44 + 47,48 - Slide of + Slide of node_modules/src/carousel/carousel.ts - 157,166 + 178,186 Currently selected slide number read by screen reader @@ -23,226 +21,226 @@ Previous node_modules/src/carousel/carousel.ts - 188,191 + 213,215 Next node_modules/src/carousel/carousel.ts - 209,211 + 236 Select month node_modules/src/datepicker/datepicker-navigation-select.ts - 41,42 + 50,51 node_modules/src/datepicker/datepicker-navigation-select.ts - 41,42 + 50,51 Select year node_modules/src/datepicker/datepicker-navigation-select.ts - 41,42 + 50,51 node_modules/src/datepicker/datepicker-navigation-select.ts - 41,42 + 50,51 Previous month node_modules/src/datepicker/datepicker-navigation.ts - 43,46 + 60,63 node_modules/src/datepicker/datepicker-navigation.ts - 43,46 + 60,63 Next month node_modules/src/datepicker/datepicker-navigation.ts - 43,46 + 60,63 node_modules/src/datepicker/datepicker-navigation.ts - 43,46 + 60,63 «« node_modules/src/pagination/pagination.ts - 224,225 + 269,270 « node_modules/src/pagination/pagination.ts - 224,225 + 269,270 » node_modules/src/pagination/pagination.ts - 224,225 + 269,270 »» node_modules/src/pagination/pagination.ts - 224,225 + 269,270 First node_modules/src/pagination/pagination.ts - 224,226 + 269,271 Previous node_modules/src/pagination/pagination.ts - 224,226 + 269,271 Next node_modules/src/pagination/pagination.ts - 224,225 + 269,271 Last node_modules/src/pagination/pagination.ts - 224,225 + 269,271 - + node_modules/src/progressbar/progressbar.ts - 23,26 + 30,33 HH node_modules/src/timepicker/timepicker.ts - 138,141 + 230,231 Hours node_modules/src/timepicker/timepicker.ts - 161 + 255,258 MM node_modules/src/timepicker/timepicker.ts - 182 + 280,282 Minutes node_modules/src/timepicker/timepicker.ts - 199 + 298,299 Increment hours node_modules/src/timepicker/timepicker.ts - 218,219 + 328,329 Decrement hours node_modules/src/timepicker/timepicker.ts - 239,240 + 350,356 Increment minutes node_modules/src/timepicker/timepicker.ts - 264,268 + 383,384 Decrement minutes node_modules/src/timepicker/timepicker.ts - 287,289 + 412,416 SS node_modules/src/timepicker/timepicker.ts - 295 + 429 Seconds node_modules/src/timepicker/timepicker.ts - 295 + 429 Increment seconds node_modules/src/timepicker/timepicker.ts - 295 + 429 Decrement seconds node_modules/src/timepicker/timepicker.ts - 295 + 429 node_modules/src/timepicker/timepicker.ts - 295 + 429 node_modules/src/timepicker/timepicker.ts - 295 + 429 Close node_modules/src/toast/toast.ts - 70,71 + 74,75 @@ -298,95 +296,113 @@ 114 + + Prev + + src/app/app.component.ts + 119 + + + + Next + + src/app/app.component.ts + 120 + + + src/app/components/document-detail/document-detail.component.html + 55 + + + + End + + src/app/app.component.ts + 121 + + 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. src/app/app.component.ts - 122 + 126 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. src/app/app.component.ts - 129 + 136 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. src/app/app.component.ts - 135 + 145 The filtering tools allow you to quickly find documents using various searches, dates, tags, etc. src/app/app.component.ts - 144 + 157 Any combination of filters can be saved as a 'view' which can then be displayed on the dashboard and / or sidebar. src/app/app.component.ts - 151 + 167 Tags, correspondents, document types and storage paths can all be managed using these pages. They can also be created from the document edit view. src/app/app.component.ts - 157 + 176 File Tasks shows you documents that have been consumed, are waiting to be, or may have failed during the process. src/app/app.component.ts - 163 + 185 - - Check out the settings for various tweaks to the web app or to toggle settings for saved views. + + Check out the settings for various tweaks to the web app, toggle settings for saved views or setup e-mail checking. src/app/app.component.ts - 169 - - - - The Admin area contains more advanced controls as well as the settings for automatic e-mail fetching. - - src/app/app.component.ts - 175 + 194 Thank you! 🙏 src/app/app.component.ts - 180 + 203 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. src/app/app.component.ts - 182 + 205 Lastly, on behalf of every contributor to this community-supported project, thank you for using Paperless-ngx! src/app/app.component.ts - 184 + 207 Initiating upload... src/app/app.component.ts - 230 + 256 @@ -491,7 +507,7 @@ src/app/components/manage/settings/settings.component.html - 184 + 189 @@ -608,22 +624,11 @@ 1 - - Admin - - src/app/components/app-frame/app-frame.component.html - 178 - - - src/app/components/app-frame/app-frame.component.html - 181 - - Info src/app/components/app-frame/app-frame.component.html - 187 + 180 src/app/components/manage/tasks/tasks.component.html @@ -634,68 +639,68 @@ Documentation src/app/components/app-frame/app-frame.component.html - 191 + 184 src/app/components/app-frame/app-frame.component.html - 194 + 187 GitHub src/app/components/app-frame/app-frame.component.html - 199 + 192 src/app/components/app-frame/app-frame.component.html - 202 + 195 Suggest an idea src/app/components/app-frame/app-frame.component.html - 204 + 197 src/app/components/app-frame/app-frame.component.html - 208 + 201 is available. src/app/components/app-frame/app-frame.component.html - 217 + 210 Click to view. src/app/components/app-frame/app-frame.component.html - 217 + 210 Paperless-ngx can automatically check for updates src/app/components/app-frame/app-frame.component.html - 221 + 214 How does this work? src/app/components/app-frame/app-frame.component.html - 228,230 + 221,223 Update available src/app/components/app-frame/app-frame.component.html - 239 + 232 @@ -706,7 +711,7 @@ src/app/components/manage/settings/settings.component.ts - 326 + 476 @@ -820,6 +825,14 @@ src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html 9 + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 10 + + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 10 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html 13 @@ -866,7 +879,15 @@ src/app/components/manage/settings/settings.component.html - 191 + 196 + + + src/app/components/manage/settings/settings.component.html + 248 + + + src/app/components/manage/settings/settings.component.html + 283 src/app/components/manage/tasks/tasks.component.html @@ -940,6 +961,14 @@ src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html 16 + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 23 + + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 35 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html 21 @@ -971,6 +1000,14 @@ src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html 17 + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 24 + + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 36 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html 22 @@ -989,60 +1026,428 @@ src/app/components/manage/settings/settings.component.html - 223 + 317 Create new correspondent src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts - 25 + 20 Edit correspondent src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts - 29 + 24 Create new document type src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts - 25 + 20 Edit document type src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts - 29 + 24 Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 52 + 49 Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 56 + 53 Could not save element: src/app/components/common/edit-dialog/edit-dialog.component.ts - 60 + 57 + + + + IMAP Server + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 11 + + + + IMAP Port + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 12 + + + + IMAP Security + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 13 + + + + Username + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 16 + + + + Password + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 17 + + + + Character Set + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 18 + + + + Create new mail account + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 22 + + + + Edit mail account + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 26 + + + + No encryption + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 43 + + + + SSL + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 44 + + + + STARTTLS + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 45 + + + + Account + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 11 + + + src/app/components/manage/settings/settings.component.html + 284 + + + + Folder + + 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. + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 12 + + + + Maximum age (days) + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 13 + + + + Attachment type + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 14 + + + + Paperless will only process mails that match all of the filters specified below. + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 17 + + + + Filter from + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 18 + + + + Filter subject + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 19 + + + + Filter body + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 20 + + + + Filter attachment filename + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 21 + + + + Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 21 + + + + Action + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 24 + + + + Action is only performed when documents are consumed from the mail. Mails without attachments remain entirely untouched. + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 24 + + + + Action parameter + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 25 + + + + Assign title from + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 26 + + + + Assign document type + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 28 + + + + Assign correspondent from + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 29 + + + + Assign correspondent + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 30 + + + + Create new mail rule + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 57 + + + + Edit mail rule + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 61 + + + + Only process attachments. + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 98 + + + + Process all files, including 'inline' attachments. + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 102 + + + + Delete + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 111 + + + src/app/components/document-detail/document-detail.component.html + 11 + + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 97 + + + src/app/components/manage/management-list/management-list.component.html + 46 + + + src/app/components/manage/management-list/management-list.component.html + 46 + + + src/app/components/manage/management-list/management-list.component.html + 46 + + + src/app/components/manage/management-list/management-list.component.html + 46 + + + src/app/components/manage/management-list/management-list.component.html + 65 + + + src/app/components/manage/management-list/management-list.component.html + 65 + + + src/app/components/manage/management-list/management-list.component.html + 65 + + + src/app/components/manage/management-list/management-list.component.html + 65 + + + src/app/components/manage/management-list/management-list.component.ts + 181 + + + src/app/components/manage/settings/settings.component.html + 214 + + + src/app/components/manage/settings/settings.component.html + 261 + + + src/app/components/manage/settings/settings.component.html + 296 + + + + Move to specified folder + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 115 + + + + Mark as read, don't process read mails + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 119 + + + + Flag the mail, don't process flagged mails + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 123 + + + + Tag the mail with specified tag, don't process tagged mails + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 127 + + + + Use subject as title + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 136 + + + + Use attachment filename as title + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 140 + + + + Do not assign a correspondent + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 149 + + + + Use mail address + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 153 + + + + Use name (or mail address if not available) + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 157 + + + + Use correspondent selected below + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 161 - Note that editing a path does not apply changes to stored files until you have run the 'document_renamer' utility. See the documentation. + Note that editing a path does not apply changes to stored files until you have run the 'document_renamer' utility. See the documentation. src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html 10 @@ -1063,35 +1468,35 @@ e.g. src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 26 + 21 or use slashes to add directories e.g. src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 28 + 23 - - See <a target="_blank" href="https://paperless-ngx.readthedocs.io/en/latest/advanced_usage.html#file-name-handling">documentation</a> for full list. + + See <a target="_blank" href="https://docs.paperless-ngx.com/advanced_usage/#file-name-handling">documentation</a> for full list. src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 30 + 25 Create new storage path src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 35 + 30 Edit storage path src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 39 + 34 @@ -1123,14 +1528,14 @@ Create new tag src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.ts - 26 + 21 Edit tag src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.ts - 30 + 25 @@ -1246,6 +1651,14 @@ src/app/components/document-list/document-list.component.html 93 + + src/app/components/manage/settings/settings.component.html + 222 + + + src/app/components/manage/settings/settings.component.html + 308 + src/app/components/manage/tasks/tasks.component.html 19 @@ -1432,7 +1845,7 @@ - More detail on how to use and configure Paperless-ngx is always available in the documentation. + More detail on how to use and configure Paperless-ngx is always available in the documentation. src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html 5 @@ -1512,57 +1925,6 @@ 5 - - Delete - - src/app/components/document-detail/document-detail.component.html - 11 - - - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 97 - - - src/app/components/manage/management-list/management-list.component.html - 46 - - - src/app/components/manage/management-list/management-list.component.html - 46 - - - src/app/components/manage/management-list/management-list.component.html - 46 - - - src/app/components/manage/management-list/management-list.component.html - 46 - - - src/app/components/manage/management-list/management-list.component.html - 65 - - - src/app/components/manage/management-list/management-list.component.html - 65 - - - src/app/components/manage/management-list/management-list.component.html - 65 - - - src/app/components/manage/management-list/management-list.component.html - 65 - - - src/app/components/manage/management-list/management-list.component.ts - 157 - - - src/app/components/manage/settings/settings.component.html - 209 - - Download @@ -1625,13 +1987,6 @@ 50 - - Next - - src/app/components/document-detail/document-detail.component.html - 55 - - Details @@ -1839,7 +2194,7 @@ src/app/components/manage/settings/settings.component.html - 154 + 159 @@ -1864,7 +2219,7 @@ src/app/components/manage/management-list/management-list.component.ts - 153 + 177 @@ -1927,6 +2282,14 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.ts 389 + + src/app/components/manage/settings/settings.component.ts + 560 + + + src/app/components/manage/settings/settings.component.ts + 619 + Proceed @@ -1938,9 +2301,17 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.ts 391 + + src/app/components/manage/settings/settings.component.ts + 562 + + + src/app/components/manage/settings/settings.component.ts + 621 + - - Redo OCR operation will begin in the background. + + Redo OCR operation will begin in the background. Close and re-open or reload this document after the operation has completed to see new content. src/app/components/document-detail/document-detail.component.ts 494 @@ -2037,7 +2408,15 @@ src/app/components/manage/settings/settings.component.html - 208 + 213 + + + src/app/components/manage/settings/settings.component.html + 250 + + + src/app/components/manage/settings/settings.component.html + 285 src/app/components/manage/tasks/tasks.component.html @@ -2299,6 +2678,14 @@ src/app/components/manage/management-list/management-list.component.html 59 + + src/app/components/manage/settings/settings.component.html + 260 + + + src/app/components/manage/settings/settings.component.html + 295 + View @@ -2659,7 +3046,7 @@ src/app/components/manage/settings/settings.component.html - 203 + 208 @@ -2670,7 +3057,7 @@ src/app/components/manage/settings/settings.component.html - 199 + 204 @@ -2861,18 +3248,46 @@ 39 + + Successfully created . + + src/app/components/manage/management-list/management-list.component.ts + 127 + + + + Error occurred while creating : . + + src/app/components/manage/management-list/management-list.component.ts + 132,134 + + + + Successfully updated . + + src/app/components/manage/management-list/management-list.component.ts + 150 + + + + Error occurred while saving : . + + src/app/components/manage/management-list/management-list.component.ts + 155,157 + + Do you really want to delete the ? src/app/components/manage/management-list/management-list.component.ts - 140 + 164 Associated documents will not be deleted. src/app/components/manage/management-list/management-list.component.ts - 155 + 179 @@ -2881,7 +3296,7 @@ )"/> src/app/components/manage/management-list/management-list.component.ts - 168,170 + 192,194 @@ -2891,333 +3306,396 @@ 2 + + Open Django Admin + + src/app/components/manage/settings/settings.component.html + 4 + + General src/app/components/manage/settings/settings.component.html - 10 + 15 Appearance src/app/components/manage/settings/settings.component.html - 13 + 18 Display language src/app/components/manage/settings/settings.component.html - 17 + 22 You need to reload the page after applying a new language. src/app/components/manage/settings/settings.component.html - 25 + 30 Date display src/app/components/manage/settings/settings.component.html - 32 + 37 Date format src/app/components/manage/settings/settings.component.html - 45 + 50 Short: src/app/components/manage/settings/settings.component.html - 51 + 56 Medium: src/app/components/manage/settings/settings.component.html - 55 + 60 Long: src/app/components/manage/settings/settings.component.html - 59 + 64 Items per page src/app/components/manage/settings/settings.component.html - 67 + 72 Document editor src/app/components/manage/settings/settings.component.html - 83 + 88 Use PDF viewer provided by the browser src/app/components/manage/settings/settings.component.html - 87 + 92 This is usually faster for displaying large PDF documents, but it might not work on some browsers. src/app/components/manage/settings/settings.component.html - 87 + 92 Sidebar src/app/components/manage/settings/settings.component.html - 94 + 99 Use 'slim' sidebar (icons only) src/app/components/manage/settings/settings.component.html - 98 + 103 Dark mode src/app/components/manage/settings/settings.component.html - 105 + 110 Use system settings src/app/components/manage/settings/settings.component.html - 108 + 113 Enable dark mode src/app/components/manage/settings/settings.component.html - 109 + 114 Invert thumbnails in dark mode src/app/components/manage/settings/settings.component.html - 110 + 115 Theme Color src/app/components/manage/settings/settings.component.html - 116 + 121 Reset src/app/components/manage/settings/settings.component.html - 125 + 130 Update checking src/app/components/manage/settings/settings.component.html - 130 + 135 Update checking works by pinging the 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/manage/settings/settings.component.html - 134,137 + 139,142 No tracking data is collected by the app in any way. src/app/components/manage/settings/settings.component.html - 139 + 144 Enable update checking src/app/components/manage/settings/settings.component.html - 141 + 146 Note that for users of thirdy-party containers e.g. linuxserver.io this notification may be 'ahead' of the current third-party release. src/app/components/manage/settings/settings.component.html - 141 + 146 Bulk editing src/app/components/manage/settings/settings.component.html - 145 + 150 Show confirmation dialogs src/app/components/manage/settings/settings.component.html - 149 + 154 Deleting documents will always ask for confirmation. src/app/components/manage/settings/settings.component.html - 149 + 154 Apply on close src/app/components/manage/settings/settings.component.html - 150 + 155 Enable comments src/app/components/manage/settings/settings.component.html - 158 + 163 Notifications src/app/components/manage/settings/settings.component.html - 166 + 171 Document processing src/app/components/manage/settings/settings.component.html - 169 + 174 Show notifications when new documents are detected src/app/components/manage/settings/settings.component.html - 173 + 178 Show notifications when document processing completes successfully src/app/components/manage/settings/settings.component.html - 174 + 179 Show notifications when document processing fails src/app/components/manage/settings/settings.component.html - 175 + 180 Suppress notifications on dashboard src/app/components/manage/settings/settings.component.html - 176 + 181 This will suppress all messages about document processing status on the dashboard. src/app/components/manage/settings/settings.component.html - 176 + 181 Appears on src/app/components/manage/settings/settings.component.html - 196 + 201 No saved views defined. src/app/components/manage/settings/settings.component.html - 213 + 218 + + + + Mail + + src/app/components/manage/settings/settings.component.html + 231 + + + + Mail accounts + + src/app/components/manage/settings/settings.component.html + 236 + + + + Add Account + + src/app/components/manage/settings/settings.component.html + 241 + + + + Server + + src/app/components/manage/settings/settings.component.html + 249 + + + + No mail accounts defined. + + src/app/components/manage/settings/settings.component.html + 267 + + + + Mail rules + + src/app/components/manage/settings/settings.component.html + 271 + + + + Add Rule + + src/app/components/manage/settings/settings.component.html + 276 + + + + No mail rules defined. + + src/app/components/manage/settings/settings.component.html + 302 Saved view "" deleted. src/app/components/manage/settings/settings.component.ts - 217 + 367 Settings saved src/app/components/manage/settings/settings.component.ts - 310 + 460 Settings were saved successfully. src/app/components/manage/settings/settings.component.ts - 311 + 461 Settings were saved successfully. Reload is required to apply some changes. src/app/components/manage/settings/settings.component.ts - 315 + 465 Reload now src/app/components/manage/settings/settings.component.ts - 316 + 466 Use system language src/app/components/manage/settings/settings.component.ts - 334 + 484 Use date format of display language src/app/components/manage/settings/settings.component.ts - 341 + 491 @@ -3226,7 +3704,91 @@ )"/> src/app/components/manage/settings/settings.component.ts - 361,363 + 511,513 + + + + Saved account "". + + src/app/components/manage/settings/settings.component.ts + 538 + + + + Error saving account: . + + src/app/components/manage/settings/settings.component.ts + 548 + + + + Confirm delete mail account + + src/app/components/manage/settings/settings.component.ts + 558 + + + + This operation will permanently this mail account. + + src/app/components/manage/settings/settings.component.ts + 559 + + + + Deleted mail account + + src/app/components/manage/settings/settings.component.ts + 568 + + + + Error deleting mail account: . + + src/app/components/manage/settings/settings.component.ts + 577 + + + + Saved rule "". + + src/app/components/manage/settings/settings.component.ts + 596 + + + + Error saving rule: . + + src/app/components/manage/settings/settings.component.ts + 607 + + + + Confirm delete mail rule + + src/app/components/manage/settings/settings.component.ts + 617 + + + + This operation will permanently this mail rule. + + src/app/components/manage/settings/settings.component.ts + 618 + + + + Deleted mail rule + + src/app/components/manage/settings/settings.component.ts + 627 + + + + Error deleting mail rule: . + + src/app/components/manage/settings/settings.component.ts + 636 diff --git a/src-ui/package-lock.json b/src-ui/package-lock.json index b6b8051df..da26a6790 100644 --- a/src-ui/package-lock.json +++ b/src-ui/package-lock.json @@ -18,22 +18,22 @@ "@angular/router": "~14.2.8", "@ng-bootstrap/ng-bootstrap": "^13.0.0", "@ng-select/ng-select": "^9.0.2", - "@ngneat/dirty-check-forms": "^3.0.2", + "@ngneat/dirty-check-forms": "^3.0.3", "@popperjs/core": "^2.11.6", "bootstrap": "^5.2.1", "file-saver": "^2.0.5", "ng2-pdf-viewer": "^9.1.2", "ngx-color": "^8.0.3", "ngx-cookie-service": "^14.0.1", - "ngx-file-drop": "^14.0.1", + "ngx-file-drop": "^14.0.2", "ngx-ui-tour-ng-bootstrap": "^11.1.0", "rxjs": "~7.5.7", - "tslib": "^2.3.1", + "tslib": "^2.4.1", "uuid": "^9.0.0", "zone.js": "~0.11.8" }, "devDependencies": { - "@angular-builders/jest": "14.0.1", + "@angular-builders/jest": "14.1.0", "@angular-devkit/build-angular": "~14.2.7", "@angular/cli": "~14.2.7", "@angular/compiler-cli": "~14.2.8", @@ -43,7 +43,7 @@ "concurrently": "7.4.0", "jest": "28.1.3", "jest-environment-jsdom": "^29.2.2", - "jest-preset-angular": "^12.2.2", + "jest-preset-angular": "^12.2.3", "ts-node": "~10.9.1", "tslint": "~6.1.3", "typescript": "~4.8.4", @@ -73,14 +73,14 @@ } }, "node_modules/@angular-builders/jest": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/@angular-builders/jest/-/jest-14.0.1.tgz", - "integrity": "sha512-ol+/u6KD7kX0AyQ8Mr6pPmsptNh89p+PJtXhcU9epzjJw1y1Y+SlXHGVWg8JseaGRfxo3FVshS/ZvTxoGsstTA==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@angular-builders/jest/-/jest-14.1.0.tgz", + "integrity": "sha512-uGXyJ40F7HXfoWwW1EK5U75sUUQ4zVireLYPUYWT1/t1vqizss0mIPR026bMWwScWJhetdopxlWcql4wfNuXyQ==", "dev": true, "dependencies": { "@angular-devkit/architect": ">=0.1400.0 < 0.1500.0", "@angular-devkit/core": "^14.0.0", - "jest-preset-angular": "12.2.0", + "jest-preset-angular": "12.2.2", "lodash": "^4.17.15" }, "engines": { @@ -105,6 +105,37 @@ "@types/tough-cookie": "*" } }, + "node_modules/@angular-builders/jest/node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/@angular-builders/jest/node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@angular-builders/jest/node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/@angular-builders/jest/node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -139,9 +170,9 @@ } }, "node_modules/@angular-builders/jest/node_modules/jest-preset-angular": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-12.2.0.tgz", - "integrity": "sha512-dXnPdcglVcJeXdnxrws3M/gxLlYWaZGU7JS+ffuiCfMzG0AO3EDo/wpsPsxvnjCZiov1uV7g7UD1dHtmOW/sEw==", + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-12.2.2.tgz", + "integrity": "sha512-aj5ZwVW6cGGzZKUn6e/jDwFgQh6FHy1zCCXWOeqFCuM3WODrbdUJ93zKrex18e9K1+PvOcP0e20yKbj3gwhfFg==", "dev": true, "dependencies": { "bs-logger": "^0.2.6", @@ -247,6 +278,18 @@ "node": ">= 4.0.0" } }, + "node_modules/@angular-builders/jest/node_modules/w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@angular-builders/jest/node_modules/whatwg-url": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", @@ -261,12 +304,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1402.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.7.tgz", - "integrity": "sha512-YZchteri2iUq5JICSH0BQjOU3ehE57+CMU8PBigcJZiaLa/GPiCuwD9QOsnwSzHJNYYx5C94uhtZUjPwUtIAIw==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.10.tgz", + "integrity": "sha512-/6YmPrgataj1jD2Uqd1ED+CG4DaZGacoeZd/89hH7hF76Nno8K18DrSOqJAEmDnOWegpSRGVLd0qP09IHmaG5w==", "devOptional": true, "dependencies": { - "@angular-devkit/core": "14.2.7", + "@angular-devkit/core": "14.2.10", "rxjs": "6.6.7" }, "engines": { @@ -294,15 +337,15 @@ "devOptional": true }, "node_modules/@angular-devkit/build-angular": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.7.tgz", - "integrity": "sha512-Y58kcEmy8bSFyODtUFQzkuoZHNCji3fzRwGCiQYdAh/mkBf53CuVWoT9q7MrvGOc7Nmo2JiuwR/b7c543eVgfw==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.10.tgz", + "integrity": "sha512-VCeZAyq4uPCJukKInaSiD4i/GgxgcU4jFlLFQtoYNmaBS4xbPOymL19forRIihiV0dwNEa2L694vRTAPMBxIfw==", "dev": true, "dependencies": { "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1402.7", - "@angular-devkit/build-webpack": "0.1402.7", - "@angular-devkit/core": "14.2.7", + "@angular-devkit/architect": "0.1402.10", + "@angular-devkit/build-webpack": "0.1402.10", + "@angular-devkit/core": "14.2.10", "@babel/core": "7.18.10", "@babel/generator": "7.18.12", "@babel/helper-annotate-as-pure": "7.18.6", @@ -313,7 +356,7 @@ "@babel/runtime": "7.18.9", "@babel/template": "7.18.10", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "14.2.7", + "@ngtools/webpack": "14.2.10", "ansi-colors": "4.1.3", "babel-loader": "8.2.5", "babel-plugin-istanbul": "6.1.1", @@ -331,7 +374,7 @@ "less": "4.1.3", "less-loader": "11.0.0", "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.0", + "loader-utils": "3.2.1", "mini-css-extract-plugin": "2.6.1", "minimatch": "5.1.0", "open": "8.4.0", @@ -419,13 +462,19 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/@angular-devkit/build-angular/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1402.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.7.tgz", - "integrity": "sha512-aDhS/ODt8BwgtnNN73R7SuMC1GgoT5Pajn1nnIWvvpGj8XchLUbguptyl2v7D2QeYXXsd34Gtx8cDOr9PxYFTA==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.10.tgz", + "integrity": "sha512-h+2MaSY7QSvoJ3R+Hvin21jVCfPGOTLdASIUk4Jmq6J3y5BSku3KSSaV8dWoBOBkFCwQyPQMRjiHoHKLpC1K7g==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1402.7", + "@angular-devkit/architect": "0.1402.10", "rxjs": "6.6.7" }, "engines": { @@ -457,9 +506,9 @@ "dev": true }, "node_modules/@angular-devkit/core": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.7.tgz", - "integrity": "sha512-83SCYP3h6fglWMgAXFDc8HfOxk9t3ugK0onATXchctvA7blW4Vx8BSg3/DgbqCv+fF380SN8bYqqLJl8fQFdzg==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.10.tgz", + "integrity": "sha512-K4AO7mROTdbhQ7chtyQd6oPwmuL+BPUh+wn6Aq1qrmYJK4UZYFOPp8fi/Ehs8meCEeywtrssOPfrOE4Gsre9dg==", "devOptional": true, "dependencies": { "ajv": "8.11.0", @@ -501,12 +550,12 @@ "devOptional": true }, "node_modules/@angular-devkit/schematics": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.7.tgz", - "integrity": "sha512-3e2dpFXWl2Z4Gfm+KgY3gAeqsyu8utJMcDIg5sWRAXDeJJdAPc5LweCa8YZEn33Zr9cl8oK+FxlOr15RCyWLcA==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.10.tgz", + "integrity": "sha512-MMp31KpJTwKHisXOq+6VOXYApq97hZxFaFmZk396X5aIFTCELUwjcezQDk+u2nEs5iK/COUfnN3plGcfJxYhQA==", "devOptional": true, "dependencies": { - "@angular-devkit/core": "14.2.7", + "@angular-devkit/core": "14.2.10", "jsonc-parser": "3.1.0", "magic-string": "0.26.2", "ora": "5.4.1", @@ -537,15 +586,15 @@ "devOptional": true }, "node_modules/@angular/cli": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.7.tgz", - "integrity": "sha512-RM4CJwtqD7cKFQ7hNGJ56s9YMeJxYqCN5Ss0SzsKN1nXYqz8HykMW8fhUbZQ9HFVy/Ml3LGoh1yGo/tXywAWcA==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.10.tgz", + "integrity": "sha512-gX9sAKOwq4lKdPWeABB7TzKDHdjQXvkUU8NmPJA6mEAVXvm3lhQtFvHDalZstwK8au2LY0LaXTcEtcKYOt3AXQ==", "devOptional": true, "dependencies": { - "@angular-devkit/architect": "0.1402.7", - "@angular-devkit/core": "14.2.7", - "@angular-devkit/schematics": "14.2.7", - "@schematics/angular": "14.2.7", + "@angular-devkit/architect": "0.1402.10", + "@angular-devkit/core": "14.2.10", + "@angular-devkit/schematics": "14.2.10", + "@schematics/angular": "14.2.10", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "debug": "4.3.4", @@ -582,9 +631,9 @@ } }, "node_modules/@angular/common": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.2.8.tgz", - "integrity": "sha512-JSPN2h1EcyWjHWtOzRQmoX48ZacTjLAYwW9ZRmBpYs6Ptw5xZ39ARTJfQNcNnJleqYju2E6BNkGnLpbtWQjNDA==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.2.12.tgz", + "integrity": "sha512-oZunh9wfInFWhNO1P8uoEs/o4u8kerKMhw8GruywKm1TV7gHDP2Fi5WHGjFqq3XYptgBTPCTSEfyLX6Cwq1PUw==", "dependencies": { "tslib": "^2.3.0" }, @@ -592,14 +641,14 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "14.2.8", + "@angular/core": "14.2.12", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.2.8.tgz", - "integrity": "sha512-lKwp3B4ZKNLgk/25Iyur8bjAwRL20auRoB4EuHrBf+928ftsjYUXTgi+0++DUjPENbpi59k6GcvMCNa6qccvIw==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.2.12.tgz", + "integrity": "sha512-u2MH9+NRwbbFDRNiPWPexed9CnCq9+pGHLuyACSP2uR6Ik68cE6cayeZbIeoEV5vWpda/XsLmJgPJysw7dAZLQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -607,7 +656,7 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "14.2.8" + "@angular/core": "14.2.12" }, "peerDependenciesMeta": { "@angular/core": { @@ -616,9 +665,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.2.8.tgz", - "integrity": "sha512-QTftNrAyXOWzKFGY6/i9jh0LB2cOxmykepG4c53wH9LblGvWFztlVOhcoU8tpQSSH8t3EYvGs2r8oUuxcYm5Cw==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.2.12.tgz", + "integrity": "sha512-9Gkb9KFkaQPz8XaS8ZwwTioRZ4ywykdAWyceICEi78/Y9ConYrTX2SbFogzI2dPUZU8a04tMlbqTSmHjVbJftQ==", "dependencies": { "@babel/core": "^7.17.2", "chokidar": "^3.0.0", @@ -640,14 +689,14 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/compiler": "14.2.8", + "@angular/compiler": "14.2.12", "typescript": ">=4.6.2 <4.9" } }, "node_modules/@angular/core": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.2.8.tgz", - "integrity": "sha512-cgnII9vJGJDLsfr7KsBfU2l+QQUmQIRIP3ImKhBxicw2IHKCSb2mYwoeLV46jaLyHyUMTLRHKUYUR4XtSPnb8A==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.2.12.tgz", + "integrity": "sha512-sGQxU5u4uawwvJa6jOTmGoisJiQ5HIN/RoBw99CmoqZIVyUSg9IRJJC1KVdH8gbpWBNLkElZv21lwJTL/msWyg==", "dependencies": { "tslib": "^2.3.0" }, @@ -656,13 +705,13 @@ }, "peerDependencies": { "rxjs": "^6.5.3 || ^7.4.0", - "zone.js": "~0.11.4" + "zone.js": "~0.11.4 || ~0.12.0" } }, "node_modules/@angular/forms": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.2.8.tgz", - "integrity": "sha512-OaL7Gi6STxJza7yn0qgmh6+hV6NVbtGmunpzrn9cR1k5TeE4ZtXu1z7VZesbZ9kZ3F6U9CmygFt0csf7j1d+Ow==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.2.12.tgz", + "integrity": "sha512-7abYlGIT2JnAtutQUlH3fQS6QEpbfftgvsVcZJCyvX0rXL3u2w2vUQkDHJH4YJJp3AHFVCH4/l7R4VcaPnrwvA==", "dependencies": { "tslib": "^2.3.0" }, @@ -670,16 +719,16 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.8", - "@angular/core": "14.2.8", - "@angular/platform-browser": "14.2.8", + "@angular/common": "14.2.12", + "@angular/core": "14.2.12", + "@angular/platform-browser": "14.2.12", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/localize": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-14.2.8.tgz", - "integrity": "sha512-ph+ZLl1sXoNnw9AH4aHyI10T0sNCUTtZeGGDTPJnfOQgqfleOvgPxCNNNdi4z02XcLjVE9CKllcaOQY8zwKlZg==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-14.2.12.tgz", + "integrity": "sha512-6TTnuvubvYL1LDIJhDfd7ygxTaj0ShTILCDXT4URBhZKQbQ3HAorDqsc6SXqZVGCHdqF0hGTaeN/7zVvgP9kzA==", "dependencies": { "@babel/core": "7.18.9", "glob": "8.0.3", @@ -694,8 +743,8 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/compiler": "14.2.8", - "@angular/compiler-cli": "14.2.8" + "@angular/compiler": "14.2.12", + "@angular/compiler-cli": "14.2.12" } }, "node_modules/@angular/localize/node_modules/@babel/core": { @@ -727,32 +776,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@angular/localize/node_modules/@babel/generator": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", - "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", - "dependencies": { - "@babel/types": "^7.18.13", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@angular/localize/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@angular/localize/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -762,9 +785,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.2.8.tgz", - "integrity": "sha512-tSASBLXoBE0/Gt6d2nC6BJ1DvbGY5wo2Lb+8WCLSvkfsgVqOh4uRuJ2a0wwjeLFd0ZNmpjG42Ijba4btmCpIjg==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.2.12.tgz", + "integrity": "sha512-vOarWym8ucl1gjYWCzdwyBha+MTvL381mvTTUu8aUx6nVhHFjv4bvpjlZnZgojecqUPyxOwmPLLHvCZPJVHZYg==", "dependencies": { "tslib": "^2.3.0" }, @@ -772,9 +795,9 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/animations": "14.2.8", - "@angular/common": "14.2.8", - "@angular/core": "14.2.8" + "@angular/animations": "14.2.12", + "@angular/common": "14.2.12", + "@angular/core": "14.2.12" }, "peerDependenciesMeta": { "@angular/animations": { @@ -783,9 +806,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.2.8.tgz", - "integrity": "sha512-CPK8wHnKke8AUKR92XrFuanaKNXDzDm3uVI3DD0NxBo+fLAkiuVaDVIGgO6n6SxQVtwjXJtMXqQuNdzUg4Q9uQ==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.2.12.tgz", + "integrity": "sha512-oZhNJeaBmgw8+KBSYpKz2RYqEDyETC+HJXH8dwIFcP6BqqwL2NE70FdSR7EnOa5c41MEtTmMCGhrJSFR60x5/w==", "dependencies": { "tslib": "^2.3.0" }, @@ -793,16 +816,16 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.8", - "@angular/compiler": "14.2.8", - "@angular/core": "14.2.8", - "@angular/platform-browser": "14.2.8" + "@angular/common": "14.2.12", + "@angular/compiler": "14.2.12", + "@angular/core": "14.2.12", + "@angular/platform-browser": "14.2.12" } }, "node_modules/@angular/router": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.2.8.tgz", - "integrity": "sha512-rbKLsa4/scPP8AxaDRQfkLqfg8CbZ163dPqHMixou90uK/dx00LjCyUeS38/otdAYNZhrD0i5nu+k65qwhLX8w==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.2.12.tgz", + "integrity": "sha512-r5tVus5RJDNc4U2v0jMtjPiAS1xDsVsJ70lS313DgZmBDHIVZP1cWIehdxwgNlGwQQtAA36eG7toBwqUU3gb/A==", "dependencies": { "tslib": "^2.3.0" }, @@ -810,9 +833,9 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.8", - "@angular/core": "14.2.8", - "@angular/platform-browser": "14.2.8", + "@angular/common": "14.2.12", + "@angular/core": "14.2.12", + "@angular/platform-browser": "14.2.12", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -834,9 +857,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", - "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", "engines": { "node": ">=6.9.0" } @@ -930,13 +953,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", - "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", "dependencies": { - "@babel/compat-data": "^7.18.8", + "@babel/compat-data": "^7.20.0", "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", + "browserslist": "^4.21.3", "semver": "^6.3.0" }, "engines": { @@ -955,17 +978,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.13.tgz", - "integrity": "sha512-hDvXp+QYxSRL+23mpAlSGxHMDyIGChm0/AwTfTAAK5Ufe40nCsyNdaYCGuK91phn/fVu9kqayImRDkvNAgdrsA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", + "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-member-expression-to-functions": "^7.18.9", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-replace-supers": "^7.19.1", "@babel/helper-split-export-declaration": "^7.18.6" }, "engines": { @@ -976,13 +999,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz", - "integrity": "sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", + "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "regexpu-core": "^5.2.1" }, "engines": { "node": ">=6.9.0" @@ -992,9 +1015,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz", - "integrity": "sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.17.7", @@ -1038,12 +1061,12 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", - "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dependencies": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1084,18 +1107,18 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", - "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1114,9 +1137,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", - "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1141,39 +1164,39 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz", - "integrity": "sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-member-expression-to-functions": "^7.18.9", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", - "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.20.0" }, "engines": { "node": ">=6.9.0" @@ -1191,17 +1214,17 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "engines": { "node": ">=6.9.0" } @@ -1215,28 +1238,28 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.18.11", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.11.tgz", - "integrity": "sha512-oBUlbv+rjZLh2Ks9SKi4aL7eKaAXBWleHzU89mP0G6BMUlRxSckk9tSIkgDGydhgFxHuGSlBQZfnaD47oBEB7w==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.18.11", - "@babel/types": "^7.18.10" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", - "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", "dependencies": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" }, "engines": { "node": ">=6.9.0" @@ -1256,9 +1279,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", - "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1446,16 +1469,16 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", - "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", + "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.8" + "@babel/plugin-transform-parameters": "^7.20.1" }, "engines": { "node": ">=6.9.0" @@ -1514,14 +1537,14 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", + "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1623,12 +1646,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", - "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", + "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1764,12 +1787,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1826,12 +1849,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", - "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz", + "integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1841,17 +1864,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz", - "integrity": "sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", + "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.20.0", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.19.1", "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" }, @@ -1878,12 +1902,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz", - "integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", + "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -2002,14 +2026,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", - "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", + "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -2019,15 +2042,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", - "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", + "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-simple-access": "^7.19.4" }, "engines": { "node": ">=6.9.0" @@ -2037,16 +2059,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz", - "integrity": "sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A==", + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", + "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-validator-identifier": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-identifier": "^7.19.1" }, "engines": { "node": ">=6.9.0" @@ -2072,13 +2093,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz", - "integrity": "sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -2119,12 +2140,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", - "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz", + "integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -2149,13 +2170,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" }, "engines": { "node": ">=6.9.0" @@ -2224,12 +2245,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz", - "integrity": "sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" }, "engines": { @@ -2455,18 +2476,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", - "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", + "@babel/generator": "^7.20.5", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.13", - "@babel/types": "^7.18.13", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2475,11 +2496,11 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", - "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", "dependencies": { - "@babel/types": "^7.18.13", + "@babel/types": "^7.20.5", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -2501,12 +2522,12 @@ } }, "node_modules/@babel/types": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", - "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", "dependencies": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2551,9 +2572,9 @@ } }, "node_modules/@csstools/postcss-cascade-layers": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.0.5.tgz", - "integrity": "sha512-Id/9wBT7FkgFzdEpiEWrsVd4ltDxN0rI0QS0SChbeQiSuux3z21SJCRLu6h2cvCEUmaRi+VD0mHFj+GJD4GFnw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", "dev": true, "dependencies": { "@csstools/selector-specificity": "^2.0.2", @@ -2878,9 +2899,9 @@ } }, "node_modules/@cypress/schematic": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-2.1.1.tgz", - "integrity": "sha512-Kf4QeNk8IVx3tdybls+xq8CbqsZwqR9dZjE3ELZhfG2rZeId9SSG6F2GpR4Xly5ROkX0BuQVeuIFNSkDxWAtPg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-2.3.0.tgz", + "integrity": "sha512-LBKX20MUUYF2Xu+1+KpVbLCoMvt2Osa80yQfonduVsLJ/p8JxtLHqufuf/ryJp9Gm9R5sDfk/YhHL+rB7a+gsg==", "optional": true, "dependencies": { "@angular-devkit/architect": "^0.1402.1", @@ -3777,12 +3798,12 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@leichtgewicht/ip-codec": { @@ -3792,9 +3813,9 @@ "dev": true }, "node_modules/@ng-bootstrap/ng-bootstrap": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-13.0.0.tgz", - "integrity": "sha512-aumflJ24VVOQ6kIGmpaWmjqfreRsXOCf/l2nOxPO6Y+d7Pit6aZthyjO7F0bRMutv6n+B/ma18GKvhhBcMepUw==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-13.1.1.tgz", + "integrity": "sha512-R6qnmFKT2EwwijBHw7rUXqyo5W90OImHOv7BlsxMNnZLIksWIhqwU00k4UBTfRTnd6JsTPuj/co3MaP61ajILA==", "dependencies": { "tslib": "^2.3.0" }, @@ -3808,9 +3829,9 @@ } }, "node_modules/@ng-select/ng-select": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-9.0.2.tgz", - "integrity": "sha512-xdNiz/kgkMWYW1qFtk/337xDk/cmfEbSVtTFxWIM2OnIX1XsQOnTlGiBYces1TsMfqS68HjAvljEkj8QIGN2Lg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-9.1.0.tgz", + "integrity": "sha512-vxSRD2d84H39eqtTJaethlpQ+xkJUU8epQNUr3yPiah23z8MBCqSDE1t0chxi+rXJz7+xoC9qFa1aYnUVFan4w==", "dependencies": { "tslib": "^2.3.1" }, @@ -3825,9 +3846,9 @@ } }, "node_modules/@ngneat/dirty-check-forms": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@ngneat/dirty-check-forms/-/dirty-check-forms-3.0.2.tgz", - "integrity": "sha512-SKl3f/SqIdBMle7QorO4T90TqaWAjLe0xtJrTrzCsjC4uQlsk+old1DugUF16FJxAikPcBMoUABHa2iT3Uh75g==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@ngneat/dirty-check-forms/-/dirty-check-forms-3.0.3.tgz", + "integrity": "sha512-YGlKrAaqTRO8lfT1xyN9LkYN0GH0crzdnXAxQFNEuNDQpCHv9cQ0j9XPDsonek6X4K7fLug84n0CQ42rSmGBqw==", "dependencies": { "tslib": ">=2.0.0" }, @@ -3835,13 +3856,14 @@ "@angular/core": ">=13.0.0", "@angular/forms": ">=13.0.0", "@angular/router": ">=13.0.0", + "lodash-es": ">=4.17.0", "rxjs": ">=6.0.0" } }, "node_modules/@ngtools/webpack": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.7.tgz", - "integrity": "sha512-I47BdEybpzjfFFMFB691o9C+69RexLTgSm/VCyDn4M8DrGrZpgYNhxN+AEr1uA6Bi6MaPG6w+TMac5tNIaO4Yw==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.10.tgz", + "integrity": "sha512-sLHapZLVub6mEz5b19tf1VfIV1w3tYfg7FNPLeni79aldxu1FbP1v2WmiFAnMzrswqyK0bhTtxrl+Z/CLKqyoQ==", "dev": true, "engines": { "node": "^14.15.0 || >=16.10.0", @@ -3942,6 +3964,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", "devOptional": true, "dependencies": { "mkdirp": "^1.0.4", @@ -3998,13 +4021,13 @@ } }, "node_modules/@schematics/angular": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.7.tgz", - "integrity": "sha512-ujtLu0gWARtJsRbN+P+McDO0Y0ygJjUN5016SdbmYDMcDJkwi+GYHU8Yvh/UONtmNor3JdV8AnZ8OmWTlswTDA==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.10.tgz", + "integrity": "sha512-YFTc/9QJdx422XcApizEcVLKoyknu8b9zHIlAepZCu7WkV8GPT0hvVEHQ7KBWys5aQ7pPZMT0JpZLeAz0F2xYQ==", "devOptional": true, "dependencies": { - "@angular-devkit/core": "14.2.7", - "@angular-devkit/schematics": "14.2.7", + "@angular-devkit/core": "14.2.10", + "@angular-devkit/schematics": "14.2.10", "jsonc-parser": "3.1.0" }, "engines": { @@ -4035,15 +4058,15 @@ "dev": true }, "node_modules/@sinclair/typebox": { - "version": "0.24.34", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.34.tgz", - "integrity": "sha512-x3ejWKw7rpy30Bvm6U0AQMOHdjqe2E3YJrBHlTxH0KFsp77bBa+MH324nJxtXZFpnTy/JW2h5HPYVm0vG2WPnw==", + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", "dev": true }, "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" @@ -4092,9 +4115,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", + "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -4124,9 +4147,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz", - "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -4171,9 +4194,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.4.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", - "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", + "version": "8.4.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", + "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", "dev": true, "dependencies": { "@types/estree": "*", @@ -4272,9 +4295,9 @@ } }, "node_modules/@types/jsdom": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.0.tgz", - "integrity": "sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==", + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", "dev": true, "dependencies": { "@types/node": "*", @@ -4295,12 +4318,12 @@ } }, "node_modules/@types/jsdom/node_modules/parse5": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", - "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, "dependencies": { - "entities": "^4.3.0" + "entities": "^4.4.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -4319,9 +4342,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.7.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.23.tgz", - "integrity": "sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg==", + "version": "18.11.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz", + "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==", "devOptional": true }, "node_modules/@types/parse-json": { @@ -4337,9 +4360,9 @@ "dev": true }, "node_modules/@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", "dev": true }, "node_modules/@types/qs": { @@ -4422,9 +4445,9 @@ } }, "node_modules/@types/yargs": { - "version": "17.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz", - "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==", + "version": "17.0.15", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz", + "integrity": "sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -4635,9 +4658,9 @@ } }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -4647,25 +4670,13 @@ } }, "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" } }, "node_modules/acorn-import-assertions": { @@ -4678,9 +4689,9 @@ } }, "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, "engines": { "node": ">=0.4.0" @@ -4700,9 +4711,9 @@ } }, "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "dependencies": { "big.js": "^5.2.2", @@ -4853,9 +4864,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -5004,9 +5015,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz", - "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==", + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", "dev": true, "funding": [ { @@ -5019,8 +5030,8 @@ } ], "dependencies": { - "browserslist": "^4.21.3", - "caniuse-lite": "^1.0.30001373", + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -5189,9 +5200,9 @@ } }, "node_modules/babel-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "dependencies": { "big.js": "^5.2.2", @@ -5202,15 +5213,6 @@ "node": ">=8.9.0" } }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "dependencies": { - "object.assign": "^4.1.0" - } - }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", @@ -5243,13 +5245,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz", - "integrity": "sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, "dependencies": { "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.2", + "@babel/helper-define-polyfill-provider": "^0.3.3", "semver": "^6.1.1" }, "peerDependencies": { @@ -5279,12 +5281,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz", - "integrity": "sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.2" + "@babel/helper-define-polyfill-provider": "^0.3.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -5500,9 +5502,9 @@ "dev": true }, "node_modules/bootstrap": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.1.tgz", - "integrity": "sha512-UQi3v2NpVPEi1n35dmRRzBJFlgvWHYwyem6yHhuT6afYF+sziEt46McRbT//kVXZ7b1YUYEVGdXEH74Nx3xzGA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz", + "integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==", "funding": [ { "type": "github", @@ -5543,9 +5545,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "funding": [ { "type": "opencollective", @@ -5557,10 +5559,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "update-browserslist-db": "^1.0.9" }, "bin": { "browserslist": "cli.js" @@ -5726,9 +5728,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001388", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001388.tgz", - "integrity": "sha512-znVbq4OUjqgLxMxoNX2ZeeLR0d7lcDiE5uJ4eUiWdml1J1EkxbnQq6opT9jb9SMfJxB0XA16/ziHwni4u1I3GQ==", + "version": "1.0.30001435", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001435.tgz", + "integrity": "sha512-kdCkUTjR+v4YAJelyiDTqiu82BDr4W4CP5sgTA0ZBmqn30XfS2ZghPLMowik9TPhS+psWJiUNxsqLyurDbmutA==", "funding": [ { "type": "opencollective", @@ -5828,10 +5830,13 @@ } }, "node_modules/ci-info": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", - "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", - "devOptional": true + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "devOptional": true, + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { "version": "1.2.2", @@ -5873,9 +5878,9 @@ } }, "node_modules/cli-table3": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", - "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "optional": true, "dependencies": { "string-width": "^4.2.0" @@ -6147,6 +6152,12 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6292,26 +6303,6 @@ "node": ">= 0.6" } }, - "node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -6322,12 +6313,9 @@ } }, "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dependencies": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/cookie": { "version": "0.5.0", @@ -6412,28 +6400,18 @@ } }, "node_modules/core-js-compat": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.0.tgz", - "integrity": "sha512-extKQM0g8/3GjFx9US12FAgx8KJawB7RCQ5y8ipYLbmfzEzmFRWdDjIlxDx82g7ygcNG85qMVUSRyABouELdow==", + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", + "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", "dev": true, "dependencies": { - "browserslist": "^4.21.3", - "semver": "7.0.0" + "browserslist": "^4.21.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, - "node_modules/core-js-compat/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -6441,9 +6419,9 @@ "devOptional": true }, "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "dependencies": { "@types/parse-json": "^4.0.0", @@ -6685,9 +6663,9 @@ } }, "node_modules/cssdb": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.0.1.tgz", - "integrity": "sha512-pT3nzyGM78poCKLAEy2zWIVX2hikq6dIrjuZzLV98MumBg+xMTNYfHx7paUlfiRTgg91O/vR889CIf+qiv79Rw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.2.0.tgz", + "integrity": "sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg==", "dev": true, "funding": { "type": "opencollective", @@ -6788,9 +6766,9 @@ } }, "node_modules/cypress/node_modules/@types/node": { - "version": "14.18.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.26.tgz", - "integrity": "sha512-0b+utRBSYj8L7XAp0d+DX7lI4cSmowNaaTkk6/1SKzbKkG+doLuPusB9EOvzLJ8ahJSk03bTLIL6cWaEd4dBKA==", + "version": "14.18.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.34.tgz", + "integrity": "sha512-hcU9AIQVHmPnmjRK+XUUYlILlr9pQrsqSrwov/JK1pnf3GTQowVBhx54FbvM0AU/VXGH4i3+vgXS5EguR7fysA==", "optional": true }, "node_modules/cypress/node_modules/ansi-styles": { @@ -6920,9 +6898,9 @@ } }, "node_modules/date-fns": { - "version": "2.29.2", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.2.tgz", - "integrity": "sha512-0VNbwmWJDS/G3ySwFSJA3ayhbURMTJLtwM2DTxf9CWondCnh6DTNlO9JgRSq6ibf4eD0lfMJNBxUdEAHHix+bA==", + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", "dev": true, "engines": { "node": ">=0.11" @@ -6933,9 +6911,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.5.tgz", - "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", + "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==", "optional": true }, "node_modules/debug": { @@ -6955,9 +6933,9 @@ } }, "node_modules/decimal.js": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", - "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", + "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==", "dev": true }, "node_modules/dedent": { @@ -7038,12 +7016,15 @@ } }, "node_modules/defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "devOptional": true, "dependencies": { "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/define-lazy-prop": { @@ -7055,22 +7036,6 @@ "node": ">=8" } }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -7265,9 +7230,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.240", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.240.tgz", - "integrity": "sha512-r20dUOtZ4vUPTqAajDGonIM1uas5tf85Up+wPdtNBNvBSqGCfkpvMVvQ1T8YJzPV9/Y9g3FbUDcXb94Rafycow==" + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "node_modules/emittery": { "version": "0.10.2", @@ -7335,9 +7300,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -8082,26 +8047,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/express/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -8170,9 +8115,9 @@ "devOptional": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -8225,9 +8170,9 @@ } }, "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "dependencies": { "bser": "2.1.1" @@ -8337,9 +8282,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "dev": true, "funding": [ { @@ -8503,9 +8448,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "dependencies": { "function-bind": "^1.1.1", @@ -8594,9 +8539,9 @@ "dev": true }, "node_modules/global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", "optional": true, "dependencies": { "ini": "2.0.0" @@ -8676,18 +8621,6 @@ "node": ">=4" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -8724,9 +8657,9 @@ "dev": true }, "node_modules/hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "devOptional": true, "dependencies": { "lru-cache": "^7.5.1" @@ -8762,6 +8695,12 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -8980,9 +8919,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", "dev": true, "engines": { "node": ">= 4" @@ -9251,9 +9190,9 @@ } }, "node_modules/is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "devOptional": true, "dependencies": { "has": "^1.0.3" @@ -9476,9 +9415,9 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { "@babel/core": "^7.12.3", @@ -10217,18 +10156,18 @@ } }, "node_modules/jest-environment-jsdom": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.2.2.tgz", - "integrity": "sha512-5mNtTcky1+RYv9kxkwMwt7fkzyX4EJUarV7iI+NQLigpV4Hz4sgfOdP4kOpCHXbkRWErV7tgXoXLm2CKtucr+A==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.3.1.tgz", + "integrity": "sha512-G46nKgiez2Gy4zvYNhayfMEAFlVHhWfncqvqS6yCd0i+a4NsSUD2WtrKSaYQrYiLQaupHXxCRi8xxVL2M9PbhA==", "dev": true, "dependencies": { - "@jest/environment": "^29.2.2", - "@jest/fake-timers": "^29.2.2", - "@jest/types": "^29.2.1", + "@jest/environment": "^29.3.1", + "@jest/fake-timers": "^29.3.1", + "@jest/types": "^29.3.1", "@types/jsdom": "^20.0.0", "@types/node": "*", - "jest-mock": "^29.2.2", - "jest-util": "^29.2.1", + "jest-mock": "^29.3.1", + "jest-util": "^29.3.1", "jsdom": "^20.0.0" }, "engines": { @@ -10244,32 +10183,32 @@ } }, "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.2.2.tgz", - "integrity": "sha512-OWn+Vhu0I1yxuGBJEFFekMYc8aGBGrY4rt47SOh/IFaI+D7ZHCk7pKRiSoZ2/Ml7b0Ony3ydmEHRx/tEOC7H1A==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz", + "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.2.2", - "@jest/types": "^29.2.1", + "@jest/fake-timers": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", - "jest-mock": "^29.2.2" + "jest-mock": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.2.2.tgz", - "integrity": "sha512-nqaW3y2aSyZDl7zQ7t1XogsxeavNpH6kkdq+EpXncIDvAkjvFD7hmhcIs1nWloengEWUoWqkqSA6MSbf9w6DgA==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz", + "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==", "dev": true, "dependencies": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.3.1", "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.2", - "jest-util": "^29.2.1" + "jest-message-util": "^29.3.1", + "jest-mock": "^29.3.1", + "jest-util": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -10288,9 +10227,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/@jest/types": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.2.1.tgz", - "integrity": "sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", + "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", "dev": true, "dependencies": { "@jest/schemas": "^29.0.0", @@ -10363,18 +10302,18 @@ } }, "node_modules/jest-environment-jsdom/node_modules/jest-message-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", - "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", + "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.2.1", + "@jest/types": "^29.3.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -10383,26 +10322,26 @@ } }, "node_modules/jest-environment-jsdom/node_modules/jest-mock": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.2.2.tgz", - "integrity": "sha512-1leySQxNAnivvbcx0sCB37itu8f4OX2S/+gxLAV4Z62shT4r4dTG9tACDywUAEZoLSr36aYUTsVp3WKwWt4PMQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz", + "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==", "dev": true, "dependencies": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.3.1", "@types/node": "*", - "jest-util": "^29.2.1" + "jest-util": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-jsdom/node_modules/jest-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.2.1.tgz", - "integrity": "sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", + "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", "dev": true, "dependencies": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -10414,9 +10353,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/pretty-format": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", - "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", + "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", "dev": true, "dependencies": { "@jest/schemas": "^29.0.0", @@ -10722,9 +10661,9 @@ } }, "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "engines": { "node": ">=6" @@ -10739,9 +10678,9 @@ } }, "node_modules/jest-preset-angular": { - "version": "12.2.2", - "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-12.2.2.tgz", - "integrity": "sha512-aj5ZwVW6cGGzZKUn6e/jDwFgQh6FHy1zCCXWOeqFCuM3WODrbdUJ93zKrex18e9K1+PvOcP0e20yKbj3gwhfFg==", + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-12.2.3.tgz", + "integrity": "sha512-9vgawXuki/lg4IRPtl5k83krWLKADTal7BBm06xNAWOK09AbHK1foXqZdVOMObsWbaMDeQ1cjba60vS/aEVY4Q==", "dev": true, "dependencies": { "bs-logger": "^0.2.6", @@ -10757,12 +10696,12 @@ "esbuild": ">=0.13.8" }, "peerDependencies": { - "@angular-devkit/build-angular": ">=0.1102.19 <15.0.0", - "@angular/compiler-cli": ">=11.2.14 <15.0.0", - "@angular/core": ">=11.2.14 <15.0.0", - "@angular/platform-browser-dynamic": ">=11.2.14 <15.0.0", + "@angular-devkit/build-angular": ">=12.2.18 <16.0.0", + "@angular/compiler-cli": ">=12.2.16 <16.0.0", + "@angular/core": ">=12.2.16 <16.0.0", + "@angular/platform-browser-dynamic": ">=12.2.16 <16.0.0", "jest": "^28.0.0", - "typescript": ">=4.3" + "typescript": ">=4.4" } }, "node_modules/jest-preset-angular/node_modules/@types/jsdom": { @@ -10776,6 +10715,37 @@ "@types/tough-cookie": "*" } }, + "node_modules/jest-preset-angular/node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/jest-preset-angular/node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-preset-angular/node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/jest-preset-angular/node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -10891,6 +10861,18 @@ "node": ">= 4.0.0" } }, + "node_modules/jest-preset-angular/node_modules/w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/jest-preset-angular/node_modules/whatwg-url": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", @@ -11762,9 +11744,9 @@ } }, "node_modules/joi": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz", - "integrity": "sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==", + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.7.0.tgz", + "integrity": "sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==", "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0", @@ -11799,18 +11781,18 @@ "optional": true }, "node_modules/jsdom": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.0.tgz", - "integrity": "sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==", + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", "dev": true, "dependencies": { "abab": "^2.0.6", - "acorn": "^8.7.1", - "acorn-globals": "^6.0.0", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", - "decimal.js": "^10.3.1", + "decimal.js": "^10.4.2", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -11818,18 +11800,17 @@ "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "^7.0.0", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^3.0.0", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", - "ws": "^8.8.0", + "ws": "^8.11.0", "xml-name-validator": "^4.0.0" }, "engines": { @@ -11871,12 +11852,12 @@ } }, "node_modules/jsdom/node_modules/parse5": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", - "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, "dependencies": { - "entities": "^4.3.0" + "entities": "^4.4.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -12211,9 +12192,9 @@ } }, "node_modules/loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true, "engines": { "node": ">= 12.13.0" @@ -12237,6 +12218,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "devOptional": true }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "peer": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -12424,9 +12411,9 @@ } }, "node_modules/lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", + "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", "devOptional": true, "engines": { "node": ">=12" @@ -12524,9 +12511,9 @@ } }, "node_modules/memfs": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.9.tgz", - "integrity": "sha512-3rm8kbrzpUGRyPKSGuk387NZOwQ90O4rI9tsWQkzNW7BLSnKGp23RsEsKK8N8QVCrtJoAMqy3spxHC4os4G6PQ==", + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.12.tgz", + "integrity": "sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==", "dev": true, "dependencies": { "fs-monkey": "^1.0.3" @@ -12676,15 +12663,18 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "devOptional": true + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "devOptional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "devOptional": true, "dependencies": { "yallist": "^4.0.0" @@ -12836,9 +12826,9 @@ "dev": true }, "node_modules/needle": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz", - "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", + "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", "dev": true, "optional": true, "dependencies": { @@ -12892,9 +12882,9 @@ "dev": true }, "node_modules/ng2-pdf-viewer": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-9.1.2.tgz", - "integrity": "sha512-dVfrEOW0rusHjLGpGnkt2mDKdd3LKK9uXAbNxOCv94I2jS2QjciPHMELLKWCliBXiLNbDOTsQdCDQPvYT3vKgQ==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-9.1.3.tgz", + "integrity": "sha512-t2Gez92xPWPfY3qzzs+iLey5NUCYwJXIzv+dU4prY96aYdacsxuOpFjORW1+a330ryMkxYEJvEQ+mgbBJr77xw==", "dependencies": { "pdfjs-dist": "~2.14.305", "tslib": "^2.3.1" @@ -12930,9 +12920,9 @@ } }, "node_modules/ngx-file-drop": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/ngx-file-drop/-/ngx-file-drop-14.0.1.tgz", - "integrity": "sha512-OSsI1Qjs273Xi+tIkCoO/ciFx6gT9wwyZ1900O4ggniOiTNByNq+xBN8DASOcAqLxvkuri8en7MtZPu+jxX/6Q==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/ngx-file-drop/-/ngx-file-drop-14.0.2.tgz", + "integrity": "sha512-tIW+Ymd2IOjUQTqMb2NiuupeRPWwKe19kHmb13gf4Iw8rkvrO6PlqqZ3EqSGPIEJOmV836FZHpM4B1xXjVQLfA==", "dependencies": { "tslib": "^2.3.0" }, @@ -12945,25 +12935,10 @@ "@angular/core": ">=14.0.0" } }, - "node_modules/ngx-ui-tour-ng-bootstrap": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/ngx-ui-tour-ng-bootstrap/-/ngx-ui-tour-ng-bootstrap-11.1.0.tgz", - "integrity": "sha512-VQbQA+c4aYtUe/6yzY6BzawDHhIxwH0uck3SpJmlhhHLmydm1OCRjlmhVJHEIPggwxGOvO5h/Vs6iLmmwxn//g==", - "dependencies": { - "ngx-ui-tour-core": "9.1.0", - "tslib": "^2.0.0" - }, - "peerDependencies": { - "@angular/common": "^14.0.0", - "@angular/core": "^14.0.0", - "@ng-bootstrap/ng-bootstrap": "^13.0.0", - "typescript": ">=3.8.0" - } - }, - "node_modules/ngx-ui-tour-ng-bootstrap/node_modules/ngx-ui-tour-core": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/ngx-ui-tour-core/-/ngx-ui-tour-core-9.1.0.tgz", - "integrity": "sha512-9fSvSoh0wUpaVFNo/D0Vs9NreL0esFBY3MFycONZD8b5SE7nX2+CZLzPbIVnigmj/KH3op5Pw8Pzkg2VHmXTcg==", + "node_modules/ngx-ui-tour-core": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/ngx-ui-tour-core/-/ngx-ui-tour-core-9.2.1.tgz", + "integrity": "sha512-KpDSeNl69S1x+jUdREIkFgHGfpAyydxAt2aRUZ263kHZskME/CpaojEmjLCB+xUxEXij9Bq9tQxtGPm5IkJlPg==", "dependencies": { "tslib": "^2.0.0" }, @@ -12975,6 +12950,21 @@ "typescript": ">=3.8.0" } }, + "node_modules/ngx-ui-tour-ng-bootstrap": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/ngx-ui-tour-ng-bootstrap/-/ngx-ui-tour-ng-bootstrap-11.3.2.tgz", + "integrity": "sha512-DEQ8ek9AGIdIPM6pGZ1Z8b0qY1kwgTppA30432CBBip7UES0KJFoT9BVHG99pA7Lx07GT9okqYh0zR3jPQh7uA==", + "dependencies": { + "ngx-ui-tour-core": "9.2.1", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/common": "^14.0.0", + "@angular/core": "^14.0.0", + "@ng-bootstrap/ng-bootstrap": "^13.0.0", + "typescript": ">=3.8.0" + } + }, "node_modules/nice-napi": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", @@ -13007,16 +12997,16 @@ } }, "node_modules/node-gyp": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.1.0.tgz", - "integrity": "sha512-HkmN0ZpQJU7FLbJauJTHkHlSVAXlNGDAzH/VYFZGDOnFyn/Na3GlNJfkudmufOdS6/jNFhy88ObzL7ERz9es1g==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.0.tgz", + "integrity": "sha512-A6rJWfXFz7TQNjpldJ915WFb1LnhO4lIve3ANPbWreuEoLoKlFT3sxIepPBkLhM27crW8YmN+pjlgbasH6cH/Q==", "devOptional": true, "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.6", "make-fetch-happen": "^10.0.3", - "nopt": "^5.0.0", + "nopt": "^6.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", "semver": "^7.3.5", @@ -13096,18 +13086,18 @@ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", "devOptional": true, "dependencies": { - "abbrev": "1" + "abbrev": "^1.0.0" }, "bin": { "nopt": "bin/nopt.js" }, "engines": { - "node": ">=6" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/normalize-package-data": { @@ -13296,9 +13286,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.1.tgz", - "integrity": "sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, "node_modules/object-inspect": { @@ -13310,33 +13300,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", @@ -14012,9 +13975,9 @@ } }, "node_modules/postcss-custom-properties": { - "version": "12.1.8", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.8.tgz", - "integrity": "sha512-8rbj8kVu00RQh2fQF81oBqtduiANu4MIxhyf0HbbStgPtnFlWn0yiaYTpLHrPnJbffVY1s9apWsIoVZcc68FxA==", + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" @@ -14027,7 +13990,7 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, "node_modules/postcss-custom-selectors": { @@ -14329,9 +14292,9 @@ } }, "node_modules/postcss-nesting": { - "version": "10.1.10", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.1.10.tgz", - "integrity": "sha512-lqd7LXCq0gWc0wKXtoKDru5wEUNjm3OryLVNRZ8OnW8km6fSNUuFrjEhU3nklxXE2jvd4qrox566acgh+xQt8w==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", "dev": true, "dependencies": { "@csstools/selector-specificity": "^2.0.0", @@ -14529,9 +14492,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -14868,9 +14831,9 @@ "dev": true }, "node_modules/regenerate-unicode-properties": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", - "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "dev": true, "dependencies": { "regenerate": "^1.4.2" @@ -14886,9 +14849,9 @@ "dev": true }, "node_modules/regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "dev": true, "dependencies": { "@babel/runtime": "^7.8.4" @@ -14901,32 +14864,32 @@ "dev": true }, "node_modules/regexpu-core": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz", - "integrity": "sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", "dev": true, "dependencies": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.0.1", - "regjsgen": "^0.6.0", - "regjsparser": "^0.8.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" }, "engines": { "node": ">=4" } }, "node_modules/regjsgen": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", - "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", "dev": true }, "node_modules/regjsparser": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", - "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, "dependencies": { "jsesc": "~0.5.0" @@ -15031,9 +14994,9 @@ } }, "node_modules/resolve-url-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "dependencies": { "big.js": "^5.2.2", @@ -15198,9 +15161,24 @@ } }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "devOptional": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -15584,10 +15562,13 @@ } }, "node_modules/shell-quote": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", - "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", - "dev": true + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/side-channel": { "version": "1.0.4", @@ -15705,9 +15686,9 @@ } }, "node_modules/socks": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", - "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "devOptional": true, "dependencies": { "ip": "^2.0.0", @@ -15919,9 +15900,9 @@ } }, "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -15957,26 +15938,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "devOptional": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -16142,9 +16103,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, "dependencies": { "has-flag": "^4.0.0", @@ -16212,9 +16173,9 @@ } }, "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.12.tgz", + "integrity": "sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==", "devOptional": true, "dependencies": { "chownr": "^2.0.0", @@ -16225,7 +16186,7 @@ "yallist": "^4.0.0" }, "engines": { - "node": ">= 10" + "node": ">=10" } }, "node_modules/terminal-link": { @@ -16629,19 +16590,10 @@ } } }, - "node_modules/ts-node/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/tslint": { "version": "6.1.3", @@ -16866,18 +16818,18 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, "engines": { "node": ">=4" @@ -16929,9 +16881,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.6.tgz", - "integrity": "sha512-We7BqM9XFlcW94Op93uW8+2LXvGezs7QA0WY+f1H7RR1q46B06W6hZF6LbmOlpCS1HU22q/6NOGTGW5sCm7NJQ==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "funding": [ { "type": "opencollective", @@ -17064,21 +17016,22 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", "dev": true, "dependencies": { "browser-process-hrtime": "^1.0.0" } }, "node_modules/w3c-xmlserializer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", - "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dev": true, "dependencies": { "xml-name-validator": "^4.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/wait-on": { @@ -17585,9 +17538,9 @@ } }, "node_modules/ws": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", - "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -17724,14 +17677,14 @@ } }, "@angular-builders/jest": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/@angular-builders/jest/-/jest-14.0.1.tgz", - "integrity": "sha512-ol+/u6KD7kX0AyQ8Mr6pPmsptNh89p+PJtXhcU9epzjJw1y1Y+SlXHGVWg8JseaGRfxo3FVshS/ZvTxoGsstTA==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@angular-builders/jest/-/jest-14.1.0.tgz", + "integrity": "sha512-uGXyJ40F7HXfoWwW1EK5U75sUUQ4zVireLYPUYWT1/t1vqizss0mIPR026bMWwScWJhetdopxlWcql4wfNuXyQ==", "dev": true, "requires": { "@angular-devkit/architect": ">=0.1400.0 < 0.1500.0", "@angular-devkit/core": "^14.0.0", - "jest-preset-angular": "12.2.0", + "jest-preset-angular": "12.2.2", "lodash": "^4.17.15" }, "dependencies": { @@ -17746,6 +17699,30 @@ "@types/tough-cookie": "*" } }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -17774,9 +17751,9 @@ } }, "jest-preset-angular": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-12.2.0.tgz", - "integrity": "sha512-dXnPdcglVcJeXdnxrws3M/gxLlYWaZGU7JS+ffuiCfMzG0AO3EDo/wpsPsxvnjCZiov1uV7g7UD1dHtmOW/sEw==", + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-12.2.2.tgz", + "integrity": "sha512-aj5ZwVW6cGGzZKUn6e/jDwFgQh6FHy1zCCXWOeqFCuM3WODrbdUJ93zKrex18e9K1+PvOcP0e20yKbj3gwhfFg==", "dev": true, "requires": { "bs-logger": "^0.2.6", @@ -17849,6 +17826,15 @@ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true }, + "w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, "whatwg-url": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", @@ -17862,12 +17848,12 @@ } }, "@angular-devkit/architect": { - "version": "0.1402.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.7.tgz", - "integrity": "sha512-YZchteri2iUq5JICSH0BQjOU3ehE57+CMU8PBigcJZiaLa/GPiCuwD9QOsnwSzHJNYYx5C94uhtZUjPwUtIAIw==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.10.tgz", + "integrity": "sha512-/6YmPrgataj1jD2Uqd1ED+CG4DaZGacoeZd/89hH7hF76Nno8K18DrSOqJAEmDnOWegpSRGVLd0qP09IHmaG5w==", "devOptional": true, "requires": { - "@angular-devkit/core": "14.2.7", + "@angular-devkit/core": "14.2.10", "rxjs": "6.6.7" }, "dependencies": { @@ -17889,15 +17875,15 @@ } }, "@angular-devkit/build-angular": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.7.tgz", - "integrity": "sha512-Y58kcEmy8bSFyODtUFQzkuoZHNCji3fzRwGCiQYdAh/mkBf53CuVWoT9q7MrvGOc7Nmo2JiuwR/b7c543eVgfw==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.10.tgz", + "integrity": "sha512-VCeZAyq4uPCJukKInaSiD4i/GgxgcU4jFlLFQtoYNmaBS4xbPOymL19forRIihiV0dwNEa2L694vRTAPMBxIfw==", "dev": true, "requires": { "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1402.7", - "@angular-devkit/build-webpack": "0.1402.7", - "@angular-devkit/core": "14.2.7", + "@angular-devkit/architect": "0.1402.10", + "@angular-devkit/build-webpack": "0.1402.10", + "@angular-devkit/core": "14.2.10", "@babel/core": "7.18.10", "@babel/generator": "7.18.12", "@babel/helper-annotate-as-pure": "7.18.6", @@ -17908,7 +17894,7 @@ "@babel/runtime": "7.18.9", "@babel/template": "7.18.10", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "14.2.7", + "@ngtools/webpack": "14.2.10", "ansi-colors": "4.1.3", "babel-loader": "8.2.5", "babel-plugin-istanbul": "6.1.1", @@ -17927,7 +17913,7 @@ "less": "4.1.3", "less-loader": "11.0.0", "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.0", + "loader-utils": "3.2.1", "mini-css-extract-plugin": "2.6.1", "minimatch": "5.1.0", "open": "8.4.0", @@ -17975,16 +17961,22 @@ "dev": true } } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true } } }, "@angular-devkit/build-webpack": { - "version": "0.1402.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.7.tgz", - "integrity": "sha512-aDhS/ODt8BwgtnNN73R7SuMC1GgoT5Pajn1nnIWvvpGj8XchLUbguptyl2v7D2QeYXXsd34Gtx8cDOr9PxYFTA==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.10.tgz", + "integrity": "sha512-h+2MaSY7QSvoJ3R+Hvin21jVCfPGOTLdASIUk4Jmq6J3y5BSku3KSSaV8dWoBOBkFCwQyPQMRjiHoHKLpC1K7g==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1402.7", + "@angular-devkit/architect": "0.1402.10", "rxjs": "6.6.7" }, "dependencies": { @@ -18006,9 +17998,9 @@ } }, "@angular-devkit/core": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.7.tgz", - "integrity": "sha512-83SCYP3h6fglWMgAXFDc8HfOxk9t3ugK0onATXchctvA7blW4Vx8BSg3/DgbqCv+fF380SN8bYqqLJl8fQFdzg==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.10.tgz", + "integrity": "sha512-K4AO7mROTdbhQ7chtyQd6oPwmuL+BPUh+wn6Aq1qrmYJK4UZYFOPp8fi/Ehs8meCEeywtrssOPfrOE4Gsre9dg==", "devOptional": true, "requires": { "ajv": "8.11.0", @@ -18036,12 +18028,12 @@ } }, "@angular-devkit/schematics": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.7.tgz", - "integrity": "sha512-3e2dpFXWl2Z4Gfm+KgY3gAeqsyu8utJMcDIg5sWRAXDeJJdAPc5LweCa8YZEn33Zr9cl8oK+FxlOr15RCyWLcA==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.10.tgz", + "integrity": "sha512-MMp31KpJTwKHisXOq+6VOXYApq97hZxFaFmZk396X5aIFTCELUwjcezQDk+u2nEs5iK/COUfnN3plGcfJxYhQA==", "devOptional": true, "requires": { - "@angular-devkit/core": "14.2.7", + "@angular-devkit/core": "14.2.10", "jsonc-parser": "3.1.0", "magic-string": "0.26.2", "ora": "5.4.1", @@ -18066,15 +18058,15 @@ } }, "@angular/cli": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.7.tgz", - "integrity": "sha512-RM4CJwtqD7cKFQ7hNGJ56s9YMeJxYqCN5Ss0SzsKN1nXYqz8HykMW8fhUbZQ9HFVy/Ml3LGoh1yGo/tXywAWcA==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.10.tgz", + "integrity": "sha512-gX9sAKOwq4lKdPWeABB7TzKDHdjQXvkUU8NmPJA6mEAVXvm3lhQtFvHDalZstwK8au2LY0LaXTcEtcKYOt3AXQ==", "devOptional": true, "requires": { - "@angular-devkit/architect": "0.1402.7", - "@angular-devkit/core": "14.2.7", - "@angular-devkit/schematics": "14.2.7", - "@schematics/angular": "14.2.7", + "@angular-devkit/architect": "0.1402.10", + "@angular-devkit/core": "14.2.10", + "@angular-devkit/schematics": "14.2.10", + "@schematics/angular": "14.2.10", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "debug": "4.3.4", @@ -18102,25 +18094,25 @@ } }, "@angular/common": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.2.8.tgz", - "integrity": "sha512-JSPN2h1EcyWjHWtOzRQmoX48ZacTjLAYwW9ZRmBpYs6Ptw5xZ39ARTJfQNcNnJleqYju2E6BNkGnLpbtWQjNDA==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.2.12.tgz", + "integrity": "sha512-oZunh9wfInFWhNO1P8uoEs/o4u8kerKMhw8GruywKm1TV7gHDP2Fi5WHGjFqq3XYptgBTPCTSEfyLX6Cwq1PUw==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.2.8.tgz", - "integrity": "sha512-lKwp3B4ZKNLgk/25Iyur8bjAwRL20auRoB4EuHrBf+928ftsjYUXTgi+0++DUjPENbpi59k6GcvMCNa6qccvIw==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.2.12.tgz", + "integrity": "sha512-u2MH9+NRwbbFDRNiPWPexed9CnCq9+pGHLuyACSP2uR6Ik68cE6cayeZbIeoEV5vWpda/XsLmJgPJysw7dAZLQ==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler-cli": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.2.8.tgz", - "integrity": "sha512-QTftNrAyXOWzKFGY6/i9jh0LB2cOxmykepG4c53wH9LblGvWFztlVOhcoU8tpQSSH8t3EYvGs2r8oUuxcYm5Cw==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.2.12.tgz", + "integrity": "sha512-9Gkb9KFkaQPz8XaS8ZwwTioRZ4ywykdAWyceICEi78/Y9ConYrTX2SbFogzI2dPUZU8a04tMlbqTSmHjVbJftQ==", "requires": { "@babel/core": "^7.17.2", "chokidar": "^3.0.0", @@ -18135,25 +18127,25 @@ } }, "@angular/core": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.2.8.tgz", - "integrity": "sha512-cgnII9vJGJDLsfr7KsBfU2l+QQUmQIRIP3ImKhBxicw2IHKCSb2mYwoeLV46jaLyHyUMTLRHKUYUR4XtSPnb8A==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.2.12.tgz", + "integrity": "sha512-sGQxU5u4uawwvJa6jOTmGoisJiQ5HIN/RoBw99CmoqZIVyUSg9IRJJC1KVdH8gbpWBNLkElZv21lwJTL/msWyg==", "requires": { "tslib": "^2.3.0" } }, "@angular/forms": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.2.8.tgz", - "integrity": "sha512-OaL7Gi6STxJza7yn0qgmh6+hV6NVbtGmunpzrn9cR1k5TeE4ZtXu1z7VZesbZ9kZ3F6U9CmygFt0csf7j1d+Ow==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.2.12.tgz", + "integrity": "sha512-7abYlGIT2JnAtutQUlH3fQS6QEpbfftgvsVcZJCyvX0rXL3u2w2vUQkDHJH4YJJp3AHFVCH4/l7R4VcaPnrwvA==", "requires": { "tslib": "^2.3.0" } }, "@angular/localize": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-14.2.8.tgz", - "integrity": "sha512-ph+ZLl1sXoNnw9AH4aHyI10T0sNCUTtZeGGDTPJnfOQgqfleOvgPxCNNNdi4z02XcLjVE9CKllcaOQY8zwKlZg==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-14.2.12.tgz", + "integrity": "sha512-6TTnuvubvYL1LDIJhDfd7ygxTaj0ShTILCDXT4URBhZKQbQ3HAorDqsc6SXqZVGCHdqF0hGTaeN/7zVvgP9kzA==", "requires": { "@babel/core": "7.18.9", "glob": "8.0.3", @@ -18182,26 +18174,6 @@ "semver": "^6.3.0" } }, - "@babel/generator": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", - "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", - "requires": { - "@babel/types": "^7.18.13", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -18210,25 +18182,25 @@ } }, "@angular/platform-browser": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.2.8.tgz", - "integrity": "sha512-tSASBLXoBE0/Gt6d2nC6BJ1DvbGY5wo2Lb+8WCLSvkfsgVqOh4uRuJ2a0wwjeLFd0ZNmpjG42Ijba4btmCpIjg==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.2.12.tgz", + "integrity": "sha512-vOarWym8ucl1gjYWCzdwyBha+MTvL381mvTTUu8aUx6nVhHFjv4bvpjlZnZgojecqUPyxOwmPLLHvCZPJVHZYg==", "requires": { "tslib": "^2.3.0" } }, "@angular/platform-browser-dynamic": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.2.8.tgz", - "integrity": "sha512-CPK8wHnKke8AUKR92XrFuanaKNXDzDm3uVI3DD0NxBo+fLAkiuVaDVIGgO6n6SxQVtwjXJtMXqQuNdzUg4Q9uQ==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.2.12.tgz", + "integrity": "sha512-oZhNJeaBmgw8+KBSYpKz2RYqEDyETC+HJXH8dwIFcP6BqqwL2NE70FdSR7EnOa5c41MEtTmMCGhrJSFR60x5/w==", "requires": { "tslib": "^2.3.0" } }, "@angular/router": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.2.8.tgz", - "integrity": "sha512-rbKLsa4/scPP8AxaDRQfkLqfg8CbZ163dPqHMixou90uK/dx00LjCyUeS38/otdAYNZhrD0i5nu+k65qwhLX8w==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.2.12.tgz", + "integrity": "sha512-r5tVus5RJDNc4U2v0jMtjPiAS1xDsVsJ70lS313DgZmBDHIVZP1cWIehdxwgNlGwQQtAA36eG7toBwqUU3gb/A==", "requires": { "tslib": "^2.3.0" } @@ -18248,9 +18220,9 @@ } }, "@babel/compat-data": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", - "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==" + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==" }, "@babel/core": { "version": "7.18.10", @@ -18323,13 +18295,13 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", - "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", "requires": { - "@babel/compat-data": "^7.18.8", + "@babel/compat-data": "^7.20.0", "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", + "browserslist": "^4.21.3", "semver": "^6.3.0" }, "dependencies": { @@ -18341,34 +18313,34 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.13.tgz", - "integrity": "sha512-hDvXp+QYxSRL+23mpAlSGxHMDyIGChm0/AwTfTAAK5Ufe40nCsyNdaYCGuK91phn/fVu9kqayImRDkvNAgdrsA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", + "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-member-expression-to-functions": "^7.18.9", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-replace-supers": "^7.19.1", "@babel/helper-split-export-declaration": "^7.18.6" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz", - "integrity": "sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", + "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "regexpu-core": "^5.2.1" } }, "@babel/helper-define-polyfill-provider": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz", - "integrity": "sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.17.7", @@ -18402,12 +18374,12 @@ } }, "@babel/helper-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", - "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "requires": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" } }, "@babel/helper-hoist-variables": { @@ -18436,18 +18408,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", - "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" } }, "@babel/helper-optimise-call-expression": { @@ -18460,9 +18432,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", - "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true }, "@babel/helper-remap-async-to-generator": { @@ -18478,33 +18450,33 @@ } }, "@babel/helper-replace-supers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz", - "integrity": "sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-member-expression-to-functions": "^7.18.9", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" } }, "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.20.2" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", - "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", "dev": true, "requires": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.20.0" } }, "@babel/helper-split-export-declaration": { @@ -18516,14 +18488,14 @@ } }, "@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==" + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" }, "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==" + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" }, "@babel/helper-validator-option": { "version": "7.18.6", @@ -18531,25 +18503,25 @@ "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" }, "@babel/helper-wrap-function": { - "version": "7.18.11", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.11.tgz", - "integrity": "sha512-oBUlbv+rjZLh2Ks9SKi4aL7eKaAXBWleHzU89mP0G6BMUlRxSckk9tSIkgDGydhgFxHuGSlBQZfnaD47oBEB7w==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.18.11", - "@babel/types": "^7.18.10" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" } }, "@babel/helpers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", - "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", "requires": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" } }, "@babel/highlight": { @@ -18563,9 +18535,9 @@ } }, "@babel/parser": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", - "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==" + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", @@ -18681,16 +18653,16 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", - "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", + "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.8" + "@babel/plugin-transform-parameters": "^7.20.1" } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -18725,14 +18697,14 @@ } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", + "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, @@ -18801,12 +18773,12 @@ } }, "@babel/plugin-syntax-import-assertions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", - "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", + "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-syntax-import-meta": { @@ -18900,12 +18872,12 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-transform-arrow-functions": { @@ -18938,26 +18910,27 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", - "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz", + "integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-classes": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz", - "integrity": "sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", + "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.20.0", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.19.1", "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" } @@ -18972,12 +18945,12 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz", - "integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", + "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-dotall-regex": { @@ -19048,39 +19021,36 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", - "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", + "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", - "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", + "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-simple-access": "^7.19.4" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz", - "integrity": "sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A==", + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", + "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-validator-identifier": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-identifier": "^7.19.1" } }, "@babel/plugin-transform-modules-umd": { @@ -19094,13 +19064,13 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz", - "integrity": "sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-new-target": { @@ -19123,12 +19093,12 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", - "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz", + "integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-property-literals": { @@ -19141,13 +19111,13 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" } }, "@babel/plugin-transform-reserved-words": { @@ -19191,12 +19161,12 @@ } }, "@babel/plugin-transform-spread": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz", - "integrity": "sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" } }, @@ -19370,28 +19340,28 @@ } }, "@babel/traverse": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", - "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", + "@babel/generator": "^7.20.5", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.13", - "@babel/types": "^7.18.13", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", "debug": "^4.1.0", "globals": "^11.1.0" }, "dependencies": { "@babel/generator": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", - "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", "requires": { - "@babel/types": "^7.18.13", + "@babel/types": "^7.20.5", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" } @@ -19409,12 +19379,12 @@ } }, "@babel/types": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", - "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", "requires": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -19452,9 +19422,9 @@ } }, "@csstools/postcss-cascade-layers": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.0.5.tgz", - "integrity": "sha512-Id/9wBT7FkgFzdEpiEWrsVd4ltDxN0rI0QS0SChbeQiSuux3z21SJCRLu6h2cvCEUmaRi+VD0mHFj+GJD4GFnw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", "dev": true, "requires": { "@csstools/selector-specificity": "^2.0.2", @@ -19627,9 +19597,9 @@ } }, "@cypress/schematic": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-2.1.1.tgz", - "integrity": "sha512-Kf4QeNk8IVx3tdybls+xq8CbqsZwqR9dZjE3ELZhfG2rZeId9SSG6F2GpR4Xly5ROkX0BuQVeuIFNSkDxWAtPg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-2.3.0.tgz", + "integrity": "sha512-LBKX20MUUYF2Xu+1+KpVbLCoMvt2Osa80yQfonduVsLJ/p8JxtLHqufuf/ryJp9Gm9R5sDfk/YhHL+rB7a+gsg==", "optional": true, "requires": { "@angular-devkit/architect": "^0.1402.1", @@ -20320,12 +20290,12 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@leichtgewicht/ip-codec": { @@ -20335,33 +20305,33 @@ "dev": true }, "@ng-bootstrap/ng-bootstrap": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-13.0.0.tgz", - "integrity": "sha512-aumflJ24VVOQ6kIGmpaWmjqfreRsXOCf/l2nOxPO6Y+d7Pit6aZthyjO7F0bRMutv6n+B/ma18GKvhhBcMepUw==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-13.1.1.tgz", + "integrity": "sha512-R6qnmFKT2EwwijBHw7rUXqyo5W90OImHOv7BlsxMNnZLIksWIhqwU00k4UBTfRTnd6JsTPuj/co3MaP61ajILA==", "requires": { "tslib": "^2.3.0" } }, "@ng-select/ng-select": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-9.0.2.tgz", - "integrity": "sha512-xdNiz/kgkMWYW1qFtk/337xDk/cmfEbSVtTFxWIM2OnIX1XsQOnTlGiBYces1TsMfqS68HjAvljEkj8QIGN2Lg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-9.1.0.tgz", + "integrity": "sha512-vxSRD2d84H39eqtTJaethlpQ+xkJUU8epQNUr3yPiah23z8MBCqSDE1t0chxi+rXJz7+xoC9qFa1aYnUVFan4w==", "requires": { "tslib": "^2.3.1" } }, "@ngneat/dirty-check-forms": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@ngneat/dirty-check-forms/-/dirty-check-forms-3.0.2.tgz", - "integrity": "sha512-SKl3f/SqIdBMle7QorO4T90TqaWAjLe0xtJrTrzCsjC4uQlsk+old1DugUF16FJxAikPcBMoUABHa2iT3Uh75g==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@ngneat/dirty-check-forms/-/dirty-check-forms-3.0.3.tgz", + "integrity": "sha512-YGlKrAaqTRO8lfT1xyN9LkYN0GH0crzdnXAxQFNEuNDQpCHv9cQ0j9XPDsonek6X4K7fLug84n0CQ42rSmGBqw==", "requires": { "tslib": ">=2.0.0" } }, "@ngtools/webpack": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.7.tgz", - "integrity": "sha512-I47BdEybpzjfFFMFB691o9C+69RexLTgSm/VCyDn4M8DrGrZpgYNhxN+AEr1uA6Bi6MaPG6w+TMac5tNIaO4Yw==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.10.tgz", + "integrity": "sha512-sLHapZLVub6mEz5b19tf1VfIV1w3tYfg7FNPLeni79aldxu1FbP1v2WmiFAnMzrswqyK0bhTtxrl+Z/CLKqyoQ==", "dev": true, "requires": {} }, @@ -20472,13 +20442,13 @@ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" }, "@schematics/angular": { - "version": "14.2.7", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.7.tgz", - "integrity": "sha512-ujtLu0gWARtJsRbN+P+McDO0Y0ygJjUN5016SdbmYDMcDJkwi+GYHU8Yvh/UONtmNor3JdV8AnZ8OmWTlswTDA==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.10.tgz", + "integrity": "sha512-YFTc/9QJdx422XcApizEcVLKoyknu8b9zHIlAepZCu7WkV8GPT0hvVEHQ7KBWys5aQ7pPZMT0JpZLeAz0F2xYQ==", "devOptional": true, "requires": { - "@angular-devkit/core": "14.2.7", - "@angular-devkit/schematics": "14.2.7", + "@angular-devkit/core": "14.2.10", + "@angular-devkit/schematics": "14.2.10", "jsonc-parser": "3.1.0" } }, @@ -20504,15 +20474,15 @@ "dev": true }, "@sinclair/typebox": { - "version": "0.24.34", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.34.tgz", - "integrity": "sha512-x3ejWKw7rpy30Bvm6U0AQMOHdjqe2E3YJrBHlTxH0KFsp77bBa+MH324nJxtXZFpnTy/JW2h5HPYVm0vG2WPnw==", + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", "dev": true }, "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -20558,9 +20528,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", + "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -20590,9 +20560,9 @@ } }, "@types/babel__traverse": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz", - "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -20637,9 +20607,9 @@ } }, "@types/eslint": { - "version": "8.4.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", - "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", + "version": "8.4.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", + "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", "dev": true, "requires": { "@types/estree": "*", @@ -20738,9 +20708,9 @@ } }, "@types/jsdom": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.0.tgz", - "integrity": "sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==", + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", "dev": true, "requires": { "@types/node": "*", @@ -20755,12 +20725,12 @@ "dev": true }, "parse5": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", - "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, "requires": { - "entities": "^4.3.0" + "entities": "^4.4.0" } } } @@ -20778,9 +20748,9 @@ "dev": true }, "@types/node": { - "version": "18.7.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.23.tgz", - "integrity": "sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg==", + "version": "18.11.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz", + "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==", "devOptional": true }, "@types/parse-json": { @@ -20796,9 +20766,9 @@ "dev": true }, "@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", "dev": true }, "@types/qs": { @@ -20881,9 +20851,9 @@ } }, "@types/yargs": { - "version": "17.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz", - "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==", + "version": "17.0.15", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz", + "integrity": "sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -21091,27 +21061,19 @@ } }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true }, "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", "dev": true, "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" } }, "acorn-import-assertions": { @@ -21122,9 +21084,9 @@ "requires": {} }, "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, "adjust-sourcemap-loader": { @@ -21138,9 +21100,9 @@ }, "dependencies": { "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -21245,9 +21207,9 @@ } }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -21366,13 +21328,13 @@ "optional": true }, "autoprefixer": { - "version": "10.4.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz", - "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==", + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", "dev": true, "requires": { - "browserslist": "^4.21.3", - "caniuse-lite": "^1.0.30001373", + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -21494,9 +21456,9 @@ }, "dependencies": { "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -21506,15 +21468,6 @@ } } }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, "babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", @@ -21541,13 +21494,13 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz", - "integrity": "sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, "requires": { "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.2", + "@babel/helper-define-polyfill-provider": "^0.3.3", "semver": "^6.1.1" }, "dependencies": { @@ -21570,12 +21523,12 @@ } }, "babel-plugin-polyfill-regenerator": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz", - "integrity": "sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.2" + "@babel/helper-define-polyfill-provider": "^0.3.3" } }, "babel-preset-current-node-syntax": { @@ -21745,9 +21698,9 @@ "dev": true }, "bootstrap": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.1.tgz", - "integrity": "sha512-UQi3v2NpVPEi1n35dmRRzBJFlgvWHYwyem6yHhuT6afYF+sziEt46McRbT//kVXZ7b1YUYEVGdXEH74Nx3xzGA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz", + "integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==", "requires": {} }, "brace-expansion": { @@ -21773,14 +21726,14 @@ "dev": true }, "browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "requires": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "update-browserslist-db": "^1.0.9" } }, "bs-logger": { @@ -21899,9 +21852,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001388", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001388.tgz", - "integrity": "sha512-znVbq4OUjqgLxMxoNX2ZeeLR0d7lcDiE5uJ4eUiWdml1J1EkxbnQq6opT9jb9SMfJxB0XA16/ziHwni4u1I3GQ==" + "version": "1.0.30001435", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001435.tgz", + "integrity": "sha512-kdCkUTjR+v4YAJelyiDTqiu82BDr4W4CP5sgTA0ZBmqn30XfS2ZghPLMowik9TPhS+psWJiUNxsqLyurDbmutA==" }, "caseless": { "version": "0.12.0", @@ -21965,9 +21918,9 @@ "dev": true }, "ci-info": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", - "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", "devOptional": true }, "cjs-module-lexer": { @@ -21998,9 +21951,9 @@ "devOptional": true }, "cli-table3": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", - "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "optional": true, "requires": { "@colors/colors": "1.5.0", @@ -22217,6 +22170,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true } } }, @@ -22324,14 +22283,6 @@ "dev": true, "requires": { "safe-buffer": "5.2.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } } }, "content-type": { @@ -22341,12 +22292,9 @@ "dev": true }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "requires": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "cookie": { "version": "0.5.0", @@ -22407,21 +22355,12 @@ } }, "core-js-compat": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.0.tgz", - "integrity": "sha512-extKQM0g8/3GjFx9US12FAgx8KJawB7RCQ5y8ipYLbmfzEzmFRWdDjIlxDx82g7ygcNG85qMVUSRyABouELdow==", + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", + "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", "dev": true, "requires": { - "browserslist": "^4.21.3", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } + "browserslist": "^4.21.4" } }, "core-util-is": { @@ -22431,9 +22370,9 @@ "devOptional": true }, "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", @@ -22605,9 +22544,9 @@ } }, "cssdb": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.0.1.tgz", - "integrity": "sha512-pT3nzyGM78poCKLAEy2zWIVX2hikq6dIrjuZzLV98MumBg+xMTNYfHx7paUlfiRTgg91O/vR889CIf+qiv79Rw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.2.0.tgz", + "integrity": "sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg==", "dev": true }, "cssesc": { @@ -22690,9 +22629,9 @@ }, "dependencies": { "@types/node": { - "version": "14.18.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.26.tgz", - "integrity": "sha512-0b+utRBSYj8L7XAp0d+DX7lI4cSmowNaaTkk6/1SKzbKkG+doLuPusB9EOvzLJ8ahJSk03bTLIL6cWaEd4dBKA==", + "version": "14.18.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.34.tgz", + "integrity": "sha512-hcU9AIQVHmPnmjRK+XUUYlILlr9pQrsqSrwov/JK1pnf3GTQowVBhx54FbvM0AU/VXGH4i3+vgXS5EguR7fysA==", "optional": true }, "ansi-styles": { @@ -22790,15 +22729,15 @@ } }, "date-fns": { - "version": "2.29.2", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.2.tgz", - "integrity": "sha512-0VNbwmWJDS/G3ySwFSJA3ayhbURMTJLtwM2DTxf9CWondCnh6DTNlO9JgRSq6ibf4eD0lfMJNBxUdEAHHix+bA==", + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", "dev": true }, "dayjs": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.5.tgz", - "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", + "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==", "optional": true }, "debug": { @@ -22810,9 +22749,9 @@ } }, "decimal.js": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", - "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", + "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==", "dev": true }, "dedent": { @@ -22874,9 +22813,9 @@ } }, "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "devOptional": true, "requires": { "clone": "^1.0.2" @@ -22888,16 +22827,6 @@ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "devOptional": true }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -23043,9 +22972,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.240", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.240.tgz", - "integrity": "sha512-r20dUOtZ4vUPTqAajDGonIM1uas5tf85Up+wPdtNBNvBSqGCfkpvMVvQ1T8YJzPV9/Y9g3FbUDcXb94Rafycow==" + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "emittery": { "version": "0.10.2", @@ -23100,9 +23029,9 @@ } }, "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -23569,12 +23498,6 @@ "requires": { "side-channel": "^1.0.4" } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true } } }, @@ -23631,9 +23554,9 @@ "devOptional": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -23680,9 +23603,9 @@ } }, "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "requires": { "bser": "2.1.1" @@ -23773,9 +23696,9 @@ } }, "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "dev": true }, "forever-agent": { @@ -23884,9 +23807,9 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -23954,9 +23877,9 @@ "dev": true }, "global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", "optional": true, "requires": { "ini": "2.0.0" @@ -24014,15 +23937,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -24053,9 +23967,9 @@ "dev": true }, "hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "devOptional": true, "requires": { "lru-cache": "^7.5.1" @@ -24088,6 +24002,12 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -24253,9 +24173,9 @@ "devOptional": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", "dev": true }, "ignore-walk": { @@ -24456,9 +24376,9 @@ } }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "devOptional": true, "requires": { "has": "^1.0.3" @@ -24612,9 +24532,9 @@ "dev": true }, "istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "requires": { "@babel/core": "^7.12.3", @@ -25154,45 +25074,45 @@ } }, "jest-environment-jsdom": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.2.2.tgz", - "integrity": "sha512-5mNtTcky1+RYv9kxkwMwt7fkzyX4EJUarV7iI+NQLigpV4Hz4sgfOdP4kOpCHXbkRWErV7tgXoXLm2CKtucr+A==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.3.1.tgz", + "integrity": "sha512-G46nKgiez2Gy4zvYNhayfMEAFlVHhWfncqvqS6yCd0i+a4NsSUD2WtrKSaYQrYiLQaupHXxCRi8xxVL2M9PbhA==", "dev": true, "requires": { - "@jest/environment": "^29.2.2", - "@jest/fake-timers": "^29.2.2", - "@jest/types": "^29.2.1", + "@jest/environment": "^29.3.1", + "@jest/fake-timers": "^29.3.1", + "@jest/types": "^29.3.1", "@types/jsdom": "^20.0.0", "@types/node": "*", - "jest-mock": "^29.2.2", - "jest-util": "^29.2.1", + "jest-mock": "^29.3.1", + "jest-util": "^29.3.1", "jsdom": "^20.0.0" }, "dependencies": { "@jest/environment": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.2.2.tgz", - "integrity": "sha512-OWn+Vhu0I1yxuGBJEFFekMYc8aGBGrY4rt47SOh/IFaI+D7ZHCk7pKRiSoZ2/Ml7b0Ony3ydmEHRx/tEOC7H1A==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz", + "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==", "dev": true, "requires": { - "@jest/fake-timers": "^29.2.2", - "@jest/types": "^29.2.1", + "@jest/fake-timers": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", - "jest-mock": "^29.2.2" + "jest-mock": "^29.3.1" } }, "@jest/fake-timers": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.2.2.tgz", - "integrity": "sha512-nqaW3y2aSyZDl7zQ7t1XogsxeavNpH6kkdq+EpXncIDvAkjvFD7hmhcIs1nWloengEWUoWqkqSA6MSbf9w6DgA==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz", + "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==", "dev": true, "requires": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.3.1", "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.2", - "jest-util": "^29.2.1" + "jest-message-util": "^29.3.1", + "jest-mock": "^29.3.1", + "jest-util": "^29.3.1" } }, "@jest/schemas": { @@ -25205,9 +25125,9 @@ } }, "@jest/types": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.2.1.tgz", - "integrity": "sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", + "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", "dev": true, "requires": { "@jest/schemas": "^29.0.0", @@ -25259,40 +25179,40 @@ "dev": true }, "jest-message-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", - "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", + "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.2.1", + "@jest/types": "^29.3.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.2.2.tgz", - "integrity": "sha512-1leySQxNAnivvbcx0sCB37itu8f4OX2S/+gxLAV4Z62shT4r4dTG9tACDywUAEZoLSr36aYUTsVp3WKwWt4PMQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz", + "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==", "dev": true, "requires": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.3.1", "@types/node": "*", - "jest-util": "^29.2.1" + "jest-util": "^29.3.1" } }, "jest-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.2.1.tgz", - "integrity": "sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", + "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", "dev": true, "requires": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -25301,9 +25221,9 @@ } }, "pretty-format": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", - "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", + "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", "dev": true, "requires": { "@jest/schemas": "^29.0.0", @@ -25534,16 +25454,16 @@ } }, "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "requires": {} }, "jest-preset-angular": { - "version": "12.2.2", - "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-12.2.2.tgz", - "integrity": "sha512-aj5ZwVW6cGGzZKUn6e/jDwFgQh6FHy1zCCXWOeqFCuM3WODrbdUJ93zKrex18e9K1+PvOcP0e20yKbj3gwhfFg==", + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-12.2.3.tgz", + "integrity": "sha512-9vgawXuki/lg4IRPtl5k83krWLKADTal7BBm06xNAWOK09AbHK1foXqZdVOMObsWbaMDeQ1cjba60vS/aEVY4Q==", "dev": true, "requires": { "bs-logger": "^0.2.6", @@ -25565,6 +25485,30 @@ "@types/tough-cookie": "*" } }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -25654,6 +25598,15 @@ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true }, + "w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, "whatwg-url": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", @@ -26315,9 +26268,9 @@ } }, "joi": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz", - "integrity": "sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==", + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.7.0.tgz", + "integrity": "sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==", "dev": true, "requires": { "@hapi/hoek": "^9.0.0", @@ -26349,18 +26302,18 @@ "optional": true }, "jsdom": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.0.tgz", - "integrity": "sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==", + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", "dev": true, "requires": { "abab": "^2.0.6", - "acorn": "^8.7.1", - "acorn-globals": "^6.0.0", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", - "decimal.js": "^10.3.1", + "decimal.js": "^10.4.2", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -26368,18 +26321,17 @@ "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "^7.0.0", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^3.0.0", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", - "ws": "^8.8.0", + "ws": "^8.11.0", "xml-name-validator": "^4.0.0" }, "dependencies": { @@ -26401,12 +26353,12 @@ } }, "parse5": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", - "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, "requires": { - "entities": "^4.3.0" + "entities": "^4.4.0" } }, "tough-cookie": { @@ -26645,9 +26597,9 @@ "dev": true }, "loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true }, "locate-path": { @@ -26665,6 +26617,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "devOptional": true }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "peer": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -26805,9 +26763,9 @@ } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", + "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", "devOptional": true }, "magic-string": { @@ -26886,9 +26844,9 @@ "dev": true }, "memfs": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.9.tgz", - "integrity": "sha512-3rm8kbrzpUGRyPKSGuk387NZOwQ90O4rI9tsWQkzNW7BLSnKGp23RsEsKK8N8QVCrtJoAMqy3spxHC4os4G6PQ==", + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.12.tgz", + "integrity": "sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==", "dev": true, "requires": { "fs-monkey": "^1.0.3" @@ -26993,15 +26951,15 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "devOptional": true }, "minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "devOptional": true, "requires": { "yallist": "^4.0.0" @@ -27115,9 +27073,9 @@ "dev": true }, "needle": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz", - "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", + "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", "dev": true, "optional": true, "requires": { @@ -27161,9 +27119,9 @@ "dev": true }, "ng2-pdf-viewer": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-9.1.2.tgz", - "integrity": "sha512-dVfrEOW0rusHjLGpGnkt2mDKdd3LKK9uXAbNxOCv94I2jS2QjciPHMELLKWCliBXiLNbDOTsQdCDQPvYT3vKgQ==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-9.1.3.tgz", + "integrity": "sha512-t2Gez92xPWPfY3qzzs+iLey5NUCYwJXIzv+dU4prY96aYdacsxuOpFjORW1+a330ryMkxYEJvEQ+mgbBJr77xw==", "requires": { "pdfjs-dist": "~2.14.305", "tslib": "^2.3.1" @@ -27188,30 +27146,28 @@ } }, "ngx-file-drop": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/ngx-file-drop/-/ngx-file-drop-14.0.1.tgz", - "integrity": "sha512-OSsI1Qjs273Xi+tIkCoO/ciFx6gT9wwyZ1900O4ggniOiTNByNq+xBN8DASOcAqLxvkuri8en7MtZPu+jxX/6Q==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/ngx-file-drop/-/ngx-file-drop-14.0.2.tgz", + "integrity": "sha512-tIW+Ymd2IOjUQTqMb2NiuupeRPWwKe19kHmb13gf4Iw8rkvrO6PlqqZ3EqSGPIEJOmV836FZHpM4B1xXjVQLfA==", "requires": { "tslib": "^2.3.0" } }, - "ngx-ui-tour-ng-bootstrap": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/ngx-ui-tour-ng-bootstrap/-/ngx-ui-tour-ng-bootstrap-11.1.0.tgz", - "integrity": "sha512-VQbQA+c4aYtUe/6yzY6BzawDHhIxwH0uck3SpJmlhhHLmydm1OCRjlmhVJHEIPggwxGOvO5h/Vs6iLmmwxn//g==", + "ngx-ui-tour-core": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/ngx-ui-tour-core/-/ngx-ui-tour-core-9.2.1.tgz", + "integrity": "sha512-KpDSeNl69S1x+jUdREIkFgHGfpAyydxAt2aRUZ263kHZskME/CpaojEmjLCB+xUxEXij9Bq9tQxtGPm5IkJlPg==", "requires": { - "ngx-ui-tour-core": "9.1.0", "tslib": "^2.0.0" - }, - "dependencies": { - "ngx-ui-tour-core": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/ngx-ui-tour-core/-/ngx-ui-tour-core-9.1.0.tgz", - "integrity": "sha512-9fSvSoh0wUpaVFNo/D0Vs9NreL0esFBY3MFycONZD8b5SE7nX2+CZLzPbIVnigmj/KH3op5Pw8Pzkg2VHmXTcg==", - "requires": { - "tslib": "^2.0.0" - } - } + } + }, + "ngx-ui-tour-ng-bootstrap": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/ngx-ui-tour-ng-bootstrap/-/ngx-ui-tour-ng-bootstrap-11.3.2.tgz", + "integrity": "sha512-DEQ8ek9AGIdIPM6pGZ1Z8b0qY1kwgTppA30432CBBip7UES0KJFoT9BVHG99pA7Lx07GT9okqYh0zR3jPQh7uA==", + "requires": { + "ngx-ui-tour-core": "9.2.1", + "tslib": "^2.0.0" } }, "nice-napi": { @@ -27239,16 +27195,16 @@ "dev": true }, "node-gyp": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.1.0.tgz", - "integrity": "sha512-HkmN0ZpQJU7FLbJauJTHkHlSVAXlNGDAzH/VYFZGDOnFyn/Na3GlNJfkudmufOdS6/jNFhy88ObzL7ERz9es1g==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.0.tgz", + "integrity": "sha512-A6rJWfXFz7TQNjpldJ915WFb1LnhO4lIve3ANPbWreuEoLoKlFT3sxIepPBkLhM27crW8YmN+pjlgbasH6cH/Q==", "devOptional": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.6", "make-fetch-happen": "^10.0.3", - "nopt": "^5.0.0", + "nopt": "^6.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", "semver": "^7.3.5", @@ -27310,12 +27266,12 @@ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", "devOptional": true, "requires": { - "abbrev": "1" + "abbrev": "^1.0.0" } }, "normalize-package-data": { @@ -27464,9 +27420,9 @@ } }, "nwsapi": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.1.tgz", - "integrity": "sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, "object-inspect": { @@ -27475,24 +27431,6 @@ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, "obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", @@ -27966,9 +27904,9 @@ } }, "postcss-custom-properties": { - "version": "12.1.8", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.8.tgz", - "integrity": "sha512-8rbj8kVu00RQh2fQF81oBqtduiANu4MIxhyf0HbbStgPtnFlWn0yiaYTpLHrPnJbffVY1s9apWsIoVZcc68FxA==", + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" @@ -28142,9 +28080,9 @@ } }, "postcss-nesting": { - "version": "10.1.10", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.1.10.tgz", - "integrity": "sha512-lqd7LXCq0gWc0wKXtoKDru5wEUNjm3OryLVNRZ8OnW8km6fSNUuFrjEhU3nklxXE2jvd4qrox566acgh+xQt8w==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", "dev": true, "requires": { "@csstools/selector-specificity": "^2.0.0", @@ -28265,9 +28203,9 @@ } }, "postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -28532,9 +28470,9 @@ "dev": true }, "regenerate-unicode-properties": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", - "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "dev": true, "requires": { "regenerate": "^1.4.2" @@ -28547,9 +28485,9 @@ "dev": true }, "regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "dev": true, "requires": { "@babel/runtime": "^7.8.4" @@ -28562,29 +28500,29 @@ "dev": true }, "regexpu-core": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz", - "integrity": "sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", "dev": true, "requires": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.0.1", - "regjsgen": "^0.6.0", - "regjsparser": "^0.8.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" } }, "regjsgen": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", - "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", "dev": true }, "regjsparser": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", - "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -28664,9 +28602,9 @@ }, "dependencies": { "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -28784,9 +28722,10 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "devOptional": true }, "safer-buffer": { "version": "2.1.2", @@ -29090,9 +29029,9 @@ "devOptional": true }, "shell-quote": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", - "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", "dev": true }, "side-channel": { @@ -29187,9 +29126,9 @@ } }, "socks": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", - "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "devOptional": true, "requires": { "ip": "^2.0.0", @@ -29362,9 +29301,9 @@ } }, "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -29391,14 +29330,6 @@ "devOptional": true, "requires": { "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "devOptional": true - } } }, "string-length": { @@ -29515,9 +29446,9 @@ } }, "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -29566,9 +29497,9 @@ "dev": true }, "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.12.tgz", + "integrity": "sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==", "devOptional": true, "requires": { "chownr": "^2.0.0", @@ -29842,20 +29773,12 @@ "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" - }, - "dependencies": { - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - } } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "tslint": { "version": "6.1.3", @@ -30025,15 +29948,15 @@ } }, "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "dev": true }, "unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true }, "unique-filename": { @@ -30073,9 +29996,9 @@ "optional": true }, "update-browserslist-db": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.6.tgz", - "integrity": "sha512-We7BqM9XFlcW94Op93uW8+2LXvGezs7QA0WY+f1H7RR1q46B06W6hZF6LbmOlpCS1HU22q/6NOGTGW5sCm7NJQ==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -30180,9 +30103,9 @@ } }, "w3c-xmlserializer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", - "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dev": true, "requires": { "xml-name-validator": "^4.0.0" @@ -30554,9 +30477,9 @@ } }, "ws": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", - "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "requires": {} }, diff --git a/src-ui/package.json b/src-ui/package.json index 39e14d274..d45868d83 100644 --- a/src-ui/package.json +++ b/src-ui/package.json @@ -23,22 +23,22 @@ "@angular/router": "~14.2.8", "@ng-bootstrap/ng-bootstrap": "^13.0.0", "@ng-select/ng-select": "^9.0.2", - "@ngneat/dirty-check-forms": "^3.0.2", + "@ngneat/dirty-check-forms": "^3.0.3", "@popperjs/core": "^2.11.6", "bootstrap": "^5.2.1", "file-saver": "^2.0.5", "ng2-pdf-viewer": "^9.1.2", "ngx-color": "^8.0.3", "ngx-cookie-service": "^14.0.1", - "ngx-file-drop": "^14.0.1", + "ngx-file-drop": "^14.0.2", "ngx-ui-tour-ng-bootstrap": "^11.1.0", "rxjs": "~7.5.7", - "tslib": "^2.3.1", + "tslib": "^2.4.1", "uuid": "^9.0.0", "zone.js": "~0.11.8" }, "devDependencies": { - "@angular-builders/jest": "14.0.1", + "@angular-builders/jest": "14.1.0", "@angular-devkit/build-angular": "~14.2.7", "@angular/cli": "~14.2.7", "@angular/compiler-cli": "~14.2.8", @@ -48,7 +48,7 @@ "concurrently": "7.4.0", "jest": "28.1.3", "jest-environment-jsdom": "^29.2.2", - "jest-preset-angular": "^12.2.2", + "jest-preset-angular": "^12.2.3", "ts-node": "~10.9.1", "tslint": "~6.1.3", "typescript": "~4.8.4", diff --git a/src-ui/src/app/app-routing.module.ts b/src-ui/src/app/app-routing.module.ts index 1627fc72d..d0b3acd0e 100644 --- a/src-ui/src/app/app-routing.module.ts +++ b/src-ui/src/app/app-routing.module.ts @@ -154,6 +154,12 @@ const routes: Routes = [ }, }, }, + { + path: 'settings/:section', + component: SettingsComponent, + canDeactivate: [DirtyFormGuard], + }, + { path: 'tasks', component: TasksComponent }, ], }, diff --git a/src-ui/src/app/app.component.ts b/src-ui/src/app/app.component.ts index d0494aa59..320e9393a 100644 --- a/src-ui/src/app/app.component.ts +++ b/src-ui/src/app/app.component.ts @@ -135,6 +135,10 @@ export class AppComponent implements OnInit, OnDestroy { } }) + const prevBtnTitle = $localize`Prev` + const nextBtnTitle = $localize`Next` + const endBtnTitle = $localize`End` + this.tourService.initialize([ { anchorId: 'tour.dashboard', @@ -142,12 +146,18 @@ export class AppComponent implements OnInit, OnDestroy { route: '/dashboard', enableBackdrop: true, delayAfterNavigation: 500, + prevBtnTitle, + nextBtnTitle, + endBtnTitle, }, { anchorId: 'tour.upload-widget', content: $localize`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.`, route: '/dashboard', enableBackdrop: true, + prevBtnTitle, + nextBtnTitle, + endBtnTitle, }, { anchorId: 'tour.documents', @@ -157,6 +167,9 @@ export class AppComponent implements OnInit, OnDestroy { placement: 'bottom', enableBackdrop: true, disableScrollToAnchor: true, + prevBtnTitle, + nextBtnTitle, + endBtnTitle, }, { anchorId: 'tour.documents-filter-editor', @@ -164,35 +177,45 @@ export class AppComponent implements OnInit, OnDestroy { route: '/documents?sort=created&reverse=1&page=1', placement: 'bottom', enableBackdrop: true, + prevBtnTitle, + nextBtnTitle, + endBtnTitle, }, { anchorId: 'tour.documents-views', content: $localize`Any combination of filters can be saved as a 'view' which can then be displayed on the dashboard and / or sidebar.`, route: '/documents?sort=created&reverse=1&page=1', enableBackdrop: true, + prevBtnTitle, + nextBtnTitle, + endBtnTitle, }, { anchorId: 'tour.tags', content: $localize`Tags, correspondents, document types and storage paths can all be managed using these pages. They can also be created from the document edit view.`, route: '/tags', enableBackdrop: true, + prevBtnTitle, + nextBtnTitle, + endBtnTitle, }, { anchorId: 'tour.file-tasks', content: $localize`File Tasks shows you documents that have been consumed, are waiting to be, or may have failed during the process.`, route: '/tasks', enableBackdrop: true, + prevBtnTitle, + nextBtnTitle, + endBtnTitle, }, { anchorId: 'tour.settings', - content: $localize`Check out the settings for various tweaks to the web app or to toggle settings for saved views.`, + content: $localize`Check out the settings for various tweaks to the web app, toggle settings for saved views or setup e-mail checking.`, route: '/settings', enableBackdrop: true, - }, - { - anchorId: 'tour.admin', - content: $localize`The Admin area contains more advanced controls as well as the settings for automatic e-mail fetching.`, - enableBackdrop: true, + prevBtnTitle, + nextBtnTitle, + endBtnTitle, }, { anchorId: 'tour.outro', @@ -202,6 +225,9 @@ export class AppComponent implements OnInit, OnDestroy { '

    ' + $localize`Lastly, on behalf of every contributor to this community-supported project, thank you for using Paperless-ngx!`, route: '/dashboard', + prevBtnTitle, + nextBtnTitle, + endBtnTitle, }, ]) diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts index 3d862b06b..65a7cda14 100644 --- a/src-ui/src/app/app.module.ts +++ b/src-ui/src/app/app.module.ts @@ -39,6 +39,7 @@ import { NgxFileDropModule } from 'ngx-file-drop' import { TextComponent } from './components/common/input/text/text.component' import { SelectComponent } from './components/common/input/select/select.component' import { CheckComponent } from './components/common/input/check/check.component' +import { PasswordComponent } from './components/common/input/password/password.component' import { SaveViewConfigDialogComponent } from './components/document-list/save-view-config-dialog/save-view-config-dialog.component' import { TagsComponent } from './components/common/input/tags/tags.component' import { IfPermissionsDirective } from './directives/if-permissions.directive' @@ -81,6 +82,8 @@ import { TourNgBootstrapModule } from 'ngx-ui-tour-ng-bootstrap' import { UserEditDialogComponent } from './components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component' import { GroupEditDialogComponent } from './components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component' import { PermissionsSelectComponent } from './components/common/permissions-select/permissions-select.component' +import { MailAccountEditDialogComponent } from './components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component' +import { MailRuleEditDialogComponent } from './components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component' import localeBe from '@angular/common/locales/be' import localeCs from '@angular/common/locales/cs' @@ -162,6 +165,7 @@ function initializeApp(settings: SettingsService) { TextComponent, SelectComponent, CheckComponent, + PasswordComponent, SaveViewConfigDialogComponent, TagsComponent, IfPermissionsDirective, @@ -189,6 +193,8 @@ function initializeApp(settings: SettingsService) { UserEditDialogComponent, GroupEditDialogComponent, PermissionsSelectComponent, + MailAccountEditDialogComponent, + MailRuleEditDialogComponent, ], imports: [ BrowserModule, diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 55dfc9890..ce0de1b39 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -17,7 +17,7 @@ - + + + + diff --git a/src-ui/src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.scss b/src-ui/src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src-ui/src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts b/src-ui/src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts new file mode 100644 index 000000000..b2edb9219 --- /dev/null +++ b/src-ui/src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts @@ -0,0 +1,50 @@ +import { Component } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap' +import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component' +import { + IMAPSecurity, + PaperlessMailAccount, +} from 'src/app/data/paperless-mail-account' +import { MailAccountService } from 'src/app/services/rest/mail-account.service' + +const IMAP_SECURITY_OPTIONS = [ + { id: IMAPSecurity.None, name: $localize`No encryption` }, + { id: IMAPSecurity.SSL, name: $localize`SSL` }, + { id: IMAPSecurity.STARTTLS, name: $localize`STARTTLS` }, +] + +@Component({ + selector: 'app-mail-account-edit-dialog', + templateUrl: './mail-account-edit-dialog.component.html', + styleUrls: ['./mail-account-edit-dialog.component.scss'], +}) +export class MailAccountEditDialogComponent extends EditDialogComponent { + constructor(service: MailAccountService, activeModal: NgbActiveModal) { + super(service, activeModal) + } + + getCreateTitle() { + return $localize`Create new mail account` + } + + getEditTitle() { + return $localize`Edit mail account` + } + + getForm(): FormGroup { + return new FormGroup({ + name: new FormControl(null), + imap_server: new FormControl(null), + imap_port: new FormControl(null), + imap_security: new FormControl(IMAPSecurity.SSL), + username: new FormControl(null), + password: new FormControl(null), + character_set: new FormControl('UTF-8'), + }) + } + + get imapSecurityOptions() { + return IMAP_SECURITY_OPTIONS + } +} diff --git a/src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html b/src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html new file mode 100644 index 000000000..a8a476c28 --- /dev/null +++ b/src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html @@ -0,0 +1,39 @@ +
    + + + +
    diff --git a/src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.scss b/src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts b/src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts new file mode 100644 index 000000000..126c4968f --- /dev/null +++ b/src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts @@ -0,0 +1,180 @@ +import { Component } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap' +import { first } from 'rxjs' +import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component' +import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent' +import { PaperlessDocumentType } from 'src/app/data/paperless-document-type' +import { PaperlessMailAccount } from 'src/app/data/paperless-mail-account' +import { + MailAction, + MailFilterAttachmentType, + MailMetadataCorrespondentOption, + MailMetadataTitleOption, + PaperlessMailRule, +} from 'src/app/data/paperless-mail-rule' +import { CorrespondentService } from 'src/app/services/rest/correspondent.service' +import { DocumentTypeService } from 'src/app/services/rest/document-type.service' +import { MailAccountService } from 'src/app/services/rest/mail-account.service' +import { MailRuleService } from 'src/app/services/rest/mail-rule.service' + +const ATTACHMENT_TYPE_OPTIONS = [ + { + id: MailFilterAttachmentType.Attachments, + name: $localize`Only process attachments.`, + }, + { + id: MailFilterAttachmentType.Everything, + name: $localize`Process all files, including 'inline' attachments.`, + }, +] + +const ACTION_OPTIONS = [ + { + id: MailAction.Delete, + name: $localize`Delete`, + }, + { + id: MailAction.Move, + name: $localize`Move to specified folder`, + }, + { + id: MailAction.MarkRead, + name: $localize`Mark as read, don't process read mails`, + }, + { + id: MailAction.Flag, + name: $localize`Flag the mail, don't process flagged mails`, + }, + { + id: MailAction.Tag, + name: $localize`Tag the mail with specified tag, don't process tagged mails`, + }, +] + +const METADATA_TITLE_OPTIONS = [ + { + id: MailMetadataTitleOption.FromSubject, + name: $localize`Use subject as title`, + }, + { + id: MailMetadataTitleOption.FromFilename, + name: $localize`Use attachment filename as title`, + }, +] + +const METADATA_CORRESPONDENT_OPTIONS = [ + { + id: MailMetadataCorrespondentOption.FromNothing, + name: $localize`Do not assign a correspondent`, + }, + { + id: MailMetadataCorrespondentOption.FromEmail, + name: $localize`Use mail address`, + }, + { + id: MailMetadataCorrespondentOption.FromName, + name: $localize`Use name (or mail address if not available)`, + }, + { + id: MailMetadataCorrespondentOption.FromCustom, + name: $localize`Use correspondent selected below`, + }, +] + +@Component({ + selector: 'app-mail-rule-edit-dialog', + templateUrl: './mail-rule-edit-dialog.component.html', + styleUrls: ['./mail-rule-edit-dialog.component.scss'], +}) +export class MailRuleEditDialogComponent extends EditDialogComponent { + accounts: PaperlessMailAccount[] + correspondents: PaperlessCorrespondent[] + documentTypes: PaperlessDocumentType[] + + constructor( + service: MailRuleService, + activeModal: NgbActiveModal, + accountService: MailAccountService, + correspondentService: CorrespondentService, + documentTypeService: DocumentTypeService + ) { + super(service, activeModal) + + accountService + .listAll() + .pipe(first()) + .subscribe((result) => (this.accounts = result.results)) + + correspondentService + .listAll() + .pipe(first()) + .subscribe((result) => (this.correspondents = result.results)) + + documentTypeService + .listAll() + .pipe(first()) + .subscribe((result) => (this.documentTypes = result.results)) + } + + getCreateTitle() { + return $localize`Create new mail rule` + } + + getEditTitle() { + return $localize`Edit mail rule` + } + + getForm(): FormGroup { + return new FormGroup({ + name: new FormControl(null), + account: new FormControl(null), + folder: new FormControl('INBOX'), + filter_from: new FormControl(null), + filter_subject: new FormControl(null), + filter_body: new FormControl(null), + filter_attachment_filename: new FormControl(null), + maximum_age: new FormControl(null), + attachment_type: new FormControl(MailFilterAttachmentType.Attachments), + action: new FormControl(MailAction.MarkRead), + action_parameter: new FormControl(null), + assign_title_from: new FormControl(MailMetadataTitleOption.FromSubject), + assign_tags: new FormControl([]), + assign_document_type: new FormControl(null), + assign_correspondent_from: new FormControl( + MailMetadataCorrespondentOption.FromNothing + ), + assign_correspondent: new FormControl(null), + }) + } + + get showCorrespondentField(): boolean { + return ( + this.objectForm?.get('assign_correspondent_from')?.value == + MailMetadataCorrespondentOption.FromCustom + ) + } + + get showActionParamField(): boolean { + return ( + this.objectForm?.get('action')?.value == MailAction.Move || + this.objectForm?.get('action')?.value == MailAction.Tag + ) + } + + get attachmentTypeOptions() { + return ATTACHMENT_TYPE_OPTIONS + } + + get actionOptions() { + return ACTION_OPTIONS + } + + get metadataTitleOptions() { + return METADATA_TITLE_OPTIONS + } + + get metadataCorrespondentOptions() { + return METADATA_CORRESPONDENT_OPTIONS + } +} diff --git a/src-ui/src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html b/src-ui/src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html index 371fb16fa..280c101a6 100644 --- a/src-ui/src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html +++ b/src-ui/src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html @@ -7,7 +7,7 @@
    diff --git a/src/documents/tests/test_consumer.py b/src/documents/tests/test_consumer.py index 3b94b889b..f6685ad02 100644 --- a/src/documents/tests/test_consumer.py +++ b/src/documents/tests/test_consumer.py @@ -2,7 +2,9 @@ import datetime import os import re import shutil +import stat import tempfile +from subprocess import CalledProcessError from unittest import mock from unittest.mock import MagicMock @@ -801,7 +803,16 @@ class TestConsumerCreatedDate(DirectoriesMixin, TestCase): class PreConsumeTestCase(TestCase): - @mock.patch("documents.consumer.Popen") + def setUp(self) -> None: + + # this prevents websocket message reports during testing. + patcher = mock.patch("documents.consumer.Consumer._send_progress") + self._send_progress = patcher.start() + self.addCleanup(patcher.stop) + + return super().setUp() + + @mock.patch("documents.consumer.run") @override_settings(PRE_CONSUME_SCRIPT=None) def test_no_pre_consume_script(self, m): c = Consumer() @@ -809,7 +820,7 @@ class PreConsumeTestCase(TestCase): c.run_pre_consume_script() m.assert_not_called() - @mock.patch("documents.consumer.Popen") + @mock.patch("documents.consumer.run") @mock.patch("documents.consumer.Consumer._send_progress") @override_settings(PRE_CONSUME_SCRIPT="does-not-exist") def test_pre_consume_script_not_found(self, m, m2): @@ -818,7 +829,7 @@ class PreConsumeTestCase(TestCase): c.path = "path-to-file" self.assertRaises(ConsumerError, c.run_pre_consume_script) - @mock.patch("documents.consumer.Popen") + @mock.patch("documents.consumer.run") def test_pre_consume_script(self, m): with tempfile.NamedTemporaryFile() as script: with override_settings(PRE_CONSUME_SCRIPT=script.name): @@ -830,14 +841,78 @@ class PreConsumeTestCase(TestCase): args, kwargs = m.call_args - command = args[0] + command = kwargs["args"] self.assertEqual(command[0], script.name) self.assertEqual(command[1], "path-to-file") + @mock.patch("documents.consumer.Consumer.log") + def test_script_with_output(self, mocked_log): + """ + GIVEN: + - A script which outputs to stdout and stderr + WHEN: + - The script is executed as a consume script + THEN: + - The script's outputs are logged + """ + with tempfile.NamedTemporaryFile(mode="w") as script: + # Write up a little script + with script.file as outfile: + outfile.write("#!/usr/bin/env bash\n") + outfile.write("echo This message goes to stdout\n") + outfile.write("echo This message goes to stderr >&2") + + # Make the file executable + st = os.stat(script.name) + os.chmod(script.name, st.st_mode | stat.S_IEXEC) + + with override_settings(PRE_CONSUME_SCRIPT=script.name): + c = Consumer() + c.path = "path-to-file" + c.run_pre_consume_script() + + mocked_log.assert_called() + + mocked_log.assert_any_call("info", "This message goes to stdout") + mocked_log.assert_any_call("warning", "This message goes to stderr") + + def test_script_exit_non_zero(self): + """ + GIVEN: + - A script which exits with a non-zero exit code + WHEN: + - The script is executed as a pre-consume script + THEN: + - A ConsumerError is raised + """ + with tempfile.NamedTemporaryFile(mode="w") as script: + # Write up a little script + with script.file as outfile: + outfile.write("#!/usr/bin/env bash\n") + outfile.write("exit 100\n") + + # Make the file executable + st = os.stat(script.name) + os.chmod(script.name, st.st_mode | stat.S_IEXEC) + + with override_settings(PRE_CONSUME_SCRIPT=script.name): + c = Consumer() + c.path = "path-to-file" + self.assertRaises(ConsumerError, c.run_pre_consume_script) + class PostConsumeTestCase(TestCase): - @mock.patch("documents.consumer.Popen") + def setUp(self) -> None: + + # this prevents websocket message reports during testing. + patcher = mock.patch("documents.consumer.Consumer._send_progress") + self._send_progress = patcher.start() + self.addCleanup(patcher.stop) + + return super().setUp() + + @mock.patch("documents.consumer.run") @override_settings(POST_CONSUME_SCRIPT=None) def test_no_post_consume_script(self, m): doc = Document.objects.create(title="Test", mime_type="application/pdf") @@ -858,7 +933,7 @@ class PostConsumeTestCase(TestCase): c.filename = "somefile.pdf" self.assertRaises(ConsumerError, c.run_post_consume_script, doc) - @mock.patch("documents.consumer.Popen") + @mock.patch("documents.consumer.run") def test_post_consume_script_simple(self, m): with tempfile.NamedTemporaryFile() as script: with override_settings(POST_CONSUME_SCRIPT=script.name): @@ -868,7 +943,7 @@ class PostConsumeTestCase(TestCase): m.assert_called_once() - @mock.patch("documents.consumer.Popen") + @mock.patch("documents.consumer.run") def test_post_consume_script_with_correspondent(self, m): with tempfile.NamedTemporaryFile() as script: with override_settings(POST_CONSUME_SCRIPT=script.name): @@ -889,7 +964,7 @@ class PostConsumeTestCase(TestCase): args, kwargs = m.call_args - command = args[0] + command = kwargs["args"] self.assertEqual(command[0], script.name) self.assertEqual(command[1], str(doc.pk)) @@ -897,3 +972,29 @@ class PostConsumeTestCase(TestCase): self.assertEqual(command[6], f"/api/documents/{doc.pk}/thumb/") self.assertEqual(command[7], "my_bank") self.assertCountEqual(command[8].split(","), ["a", "b"]) + + def test_script_exit_non_zero(self): + """ + GIVEN: + - A script which exits with a non-zero exit code + WHEN: + - The script is executed as a post-consume script + THEN: + - A ConsumerError is raised + """ + with tempfile.NamedTemporaryFile(mode="w") as script: + # Write up a little script + with script.file as outfile: + outfile.write("#!/usr/bin/env bash\n") + outfile.write("exit -500\n") + + # Make the file executable + st = os.stat(script.name) + os.chmod(script.name, st.st_mode | stat.S_IEXEC) + + with override_settings(POST_CONSUME_SCRIPT=script.name): + c = Consumer() + doc = Document.objects.create(title="Test", mime_type="application/pdf") + c.path = "path-to-file" + with self.assertRaises(ConsumerError): + c.run_post_consume_script(doc) diff --git a/src/locale/ar_BH/LC_MESSAGES/django.po b/src/locale/ar_BH/LC_MESSAGES/django.po deleted file mode 100644 index c2f70f7bb..000000000 --- a/src/locale/ar_BH/LC_MESSAGES/django.po +++ /dev/null @@ -1,698 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: paperless-ng\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-16 09:38+0000\n" -"PO-Revision-Date: 2021-11-23 18:07\n" -"Last-Translator: \n" -"Language-Team: Arabic, Bahrain\n" -"Language: ar_BH\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n" -"X-Crowdin-Project: paperless-ng\n" -"X-Crowdin-Project-ID: 434940\n" -"X-Crowdin-Language: ar-BH\n" -"X-Crowdin-File: /dev/src/locale/en_US/LC_MESSAGES/django.po\n" -"X-Crowdin-File-ID: 54\n" - -#: documents/apps.py:10 -msgid "Documents" -msgstr "" - -#: documents/models.py:32 -msgid "Any word" -msgstr "" - -#: documents/models.py:33 -msgid "All words" -msgstr "" - -#: documents/models.py:34 -msgid "Exact match" -msgstr "" - -#: documents/models.py:35 -msgid "Regular expression" -msgstr "" - -#: documents/models.py:36 -msgid "Fuzzy word" -msgstr "" - -#: documents/models.py:37 -msgid "Automatic" -msgstr "" - -#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25 -#: paperless_mail/models.py:117 -msgid "name" -msgstr "" - -#: documents/models.py:45 -msgid "match" -msgstr "" - -#: documents/models.py:49 -msgid "matching algorithm" -msgstr "" - -#: documents/models.py:55 -msgid "is insensitive" -msgstr "" - -#: documents/models.py:74 documents/models.py:120 -msgid "correspondent" -msgstr "" - -#: documents/models.py:75 -msgid "correspondents" -msgstr "" - -#: documents/models.py:81 -msgid "color" -msgstr "" - -#: documents/models.py:87 -msgid "is inbox tag" -msgstr "" - -#: documents/models.py:89 -msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." -msgstr "" - -#: documents/models.py:94 -msgid "tag" -msgstr "" - -#: documents/models.py:95 documents/models.py:151 -msgid "tags" -msgstr "" - -#: documents/models.py:101 documents/models.py:133 -msgid "document type" -msgstr "" - -#: documents/models.py:102 -msgid "document types" -msgstr "" - -#: documents/models.py:110 -msgid "Unencrypted" -msgstr "" - -#: documents/models.py:111 -msgid "Encrypted with GNU Privacy Guard" -msgstr "" - -#: documents/models.py:124 -msgid "title" -msgstr "" - -#: documents/models.py:137 -msgid "content" -msgstr "" - -#: documents/models.py:139 -msgid "The raw, text-only data of the document. This field is primarily used for searching." -msgstr "" - -#: documents/models.py:144 -msgid "mime type" -msgstr "" - -#: documents/models.py:155 -msgid "checksum" -msgstr "" - -#: documents/models.py:159 -msgid "The checksum of the original document." -msgstr "" - -#: documents/models.py:163 -msgid "archive checksum" -msgstr "" - -#: documents/models.py:168 -msgid "The checksum of the archived document." -msgstr "" - -#: documents/models.py:172 documents/models.py:328 -msgid "created" -msgstr "" - -#: documents/models.py:176 -msgid "modified" -msgstr "" - -#: documents/models.py:180 -msgid "storage type" -msgstr "" - -#: documents/models.py:188 -msgid "added" -msgstr "" - -#: documents/models.py:192 -msgid "filename" -msgstr "" - -#: documents/models.py:198 -msgid "Current filename in storage" -msgstr "" - -#: documents/models.py:202 -msgid "archive filename" -msgstr "" - -#: documents/models.py:208 -msgid "Current archive filename in storage" -msgstr "" - -#: documents/models.py:212 -msgid "archive serial number" -msgstr "" - -#: documents/models.py:217 -msgid "The position of this document in your physical document archive." -msgstr "" - -#: documents/models.py:223 -msgid "document" -msgstr "" - -#: documents/models.py:224 -msgid "documents" -msgstr "" - -#: documents/models.py:311 -msgid "debug" -msgstr "" - -#: documents/models.py:312 -msgid "information" -msgstr "" - -#: documents/models.py:313 -msgid "warning" -msgstr "" - -#: documents/models.py:314 -msgid "error" -msgstr "" - -#: documents/models.py:315 -msgid "critical" -msgstr "" - -#: documents/models.py:319 -msgid "group" -msgstr "" - -#: documents/models.py:322 -msgid "message" -msgstr "" - -#: documents/models.py:325 -msgid "level" -msgstr "" - -#: documents/models.py:332 -msgid "log" -msgstr "" - -#: documents/models.py:333 -msgid "logs" -msgstr "" - -#: documents/models.py:344 documents/models.py:401 -msgid "saved view" -msgstr "" - -#: documents/models.py:345 -msgid "saved views" -msgstr "" - -#: documents/models.py:348 -msgid "user" -msgstr "" - -#: documents/models.py:354 -msgid "show on dashboard" -msgstr "" - -#: documents/models.py:357 -msgid "show in sidebar" -msgstr "" - -#: documents/models.py:361 -msgid "sort field" -msgstr "" - -#: documents/models.py:367 -msgid "sort reverse" -msgstr "" - -#: documents/models.py:373 -msgid "title contains" -msgstr "" - -#: documents/models.py:374 -msgid "content contains" -msgstr "" - -#: documents/models.py:375 -msgid "ASN is" -msgstr "" - -#: documents/models.py:376 -msgid "correspondent is" -msgstr "" - -#: documents/models.py:377 -msgid "document type is" -msgstr "" - -#: documents/models.py:378 -msgid "is in inbox" -msgstr "" - -#: documents/models.py:379 -msgid "has tag" -msgstr "" - -#: documents/models.py:380 -msgid "has any tag" -msgstr "" - -#: documents/models.py:381 -msgid "created before" -msgstr "" - -#: documents/models.py:382 -msgid "created after" -msgstr "" - -#: documents/models.py:383 -msgid "created year is" -msgstr "" - -#: documents/models.py:384 -msgid "created month is" -msgstr "" - -#: documents/models.py:385 -msgid "created day is" -msgstr "" - -#: documents/models.py:386 -msgid "added before" -msgstr "" - -#: documents/models.py:387 -msgid "added after" -msgstr "" - -#: documents/models.py:388 -msgid "modified before" -msgstr "" - -#: documents/models.py:389 -msgid "modified after" -msgstr "" - -#: documents/models.py:390 -msgid "does not have tag" -msgstr "" - -#: documents/models.py:391 -msgid "does not have ASN" -msgstr "" - -#: documents/models.py:392 -msgid "title or content contains" -msgstr "" - -#: documents/models.py:393 -msgid "fulltext query" -msgstr "" - -#: documents/models.py:394 -msgid "more like this" -msgstr "" - -#: documents/models.py:405 -msgid "rule type" -msgstr "" - -#: documents/models.py:409 -msgid "value" -msgstr "" - -#: documents/models.py:415 -msgid "filter rule" -msgstr "" - -#: documents/models.py:416 -msgid "filter rules" -msgstr "" - -#: documents/serialisers.py:53 -#, python-format -msgid "Invalid regular expression: %(error)s" -msgstr "" - -#: documents/serialisers.py:177 -msgid "Invalid color." -msgstr "" - -#: documents/serialisers.py:451 -#, python-format -msgid "File type %(type)s not supported" -msgstr "" - -#: documents/templates/index.html:22 -msgid "Paperless-ng is loading..." -msgstr "" - -#: documents/templates/registration/logged_out.html:14 -msgid "Paperless-ng signed out" -msgstr "" - -#: documents/templates/registration/logged_out.html:45 -msgid "You have been successfully logged out. Bye!" -msgstr "" - -#: documents/templates/registration/logged_out.html:46 -msgid "Sign in again" -msgstr "" - -#: documents/templates/registration/login.html:15 -msgid "Paperless-ng sign in" -msgstr "" - -#: documents/templates/registration/login.html:47 -msgid "Please sign in." -msgstr "" - -#: documents/templates/registration/login.html:50 -msgid "Your username and password didn't match. Please try again." -msgstr "" - -#: documents/templates/registration/login.html:53 -msgid "Username" -msgstr "" - -#: documents/templates/registration/login.html:54 -msgid "Password" -msgstr "" - -#: documents/templates/registration/login.html:59 -msgid "Sign in" -msgstr "" - -#: paperless/settings.py:303 -msgid "English (US)" -msgstr "" - -#: paperless/settings.py:304 -msgid "English (GB)" -msgstr "" - -#: paperless/settings.py:305 -msgid "German" -msgstr "" - -#: paperless/settings.py:306 -msgid "Dutch" -msgstr "" - -#: paperless/settings.py:307 -msgid "French" -msgstr "" - -#: paperless/settings.py:308 -msgid "Portuguese (Brazil)" -msgstr "" - -#: paperless/settings.py:309 -msgid "Portuguese" -msgstr "" - -#: paperless/settings.py:310 -msgid "Italian" -msgstr "" - -#: paperless/settings.py:311 -msgid "Romanian" -msgstr "" - -#: paperless/settings.py:312 -msgid "Russian" -msgstr "" - -#: paperless/settings.py:313 -msgid "Spanish" -msgstr "" - -#: paperless/settings.py:314 -msgid "Polish" -msgstr "" - -#: paperless/settings.py:315 -msgid "Swedish" -msgstr "" - -#: paperless/urls.py:120 -msgid "Paperless-ng administration" -msgstr "" - -#: paperless_mail/admin.py:15 -msgid "Authentication" -msgstr "" - -#: paperless_mail/admin.py:18 -msgid "Advanced settings" -msgstr "" - -#: paperless_mail/admin.py:37 -msgid "Filter" -msgstr "" - -#: paperless_mail/admin.py:39 -msgid "Paperless will only process mails that match ALL of the filters given below." -msgstr "" - -#: paperless_mail/admin.py:49 -msgid "Actions" -msgstr "" - -#: paperless_mail/admin.py:51 -msgid "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched." -msgstr "" - -#: paperless_mail/admin.py:58 -msgid "Metadata" -msgstr "" - -#: paperless_mail/admin.py:60 -msgid "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined." -msgstr "" - -#: paperless_mail/apps.py:9 -msgid "Paperless mail" -msgstr "" - -#: paperless_mail/models.py:11 -msgid "mail account" -msgstr "" - -#: paperless_mail/models.py:12 -msgid "mail accounts" -msgstr "" - -#: paperless_mail/models.py:19 -msgid "No encryption" -msgstr "" - -#: paperless_mail/models.py:20 -msgid "Use SSL" -msgstr "" - -#: paperless_mail/models.py:21 -msgid "Use STARTTLS" -msgstr "" - -#: paperless_mail/models.py:29 -msgid "IMAP server" -msgstr "" - -#: paperless_mail/models.py:33 -msgid "IMAP port" -msgstr "" - -#: paperless_mail/models.py:36 -msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections." -msgstr "" - -#: paperless_mail/models.py:40 -msgid "IMAP security" -msgstr "" - -#: paperless_mail/models.py:46 -msgid "username" -msgstr "" - -#: paperless_mail/models.py:50 -msgid "password" -msgstr "" - -#: paperless_mail/models.py:54 -msgid "character set" -msgstr "" - -#: paperless_mail/models.py:57 -msgid "The character set to use when communicating with the mail server, such as 'UTF-8' or 'US-ASCII'." -msgstr "" - -#: paperless_mail/models.py:68 -msgid "mail rule" -msgstr "" - -#: paperless_mail/models.py:69 -msgid "mail rules" -msgstr "" - -#: paperless_mail/models.py:75 -msgid "Only process attachments." -msgstr "" - -#: paperless_mail/models.py:76 -msgid "Process all files, including 'inline' attachments." -msgstr "" - -#: paperless_mail/models.py:86 -msgid "Mark as read, don't process read mails" -msgstr "" - -#: paperless_mail/models.py:87 -msgid "Flag the mail, don't process flagged mails" -msgstr "" - -#: paperless_mail/models.py:88 -msgid "Move to specified folder" -msgstr "" - -#: paperless_mail/models.py:89 -msgid "Delete" -msgstr "" - -#: paperless_mail/models.py:96 -msgid "Use subject as title" -msgstr "" - -#: paperless_mail/models.py:97 -msgid "Use attachment filename as title" -msgstr "" - -#: paperless_mail/models.py:107 -msgid "Do not assign a correspondent" -msgstr "" - -#: paperless_mail/models.py:109 -msgid "Use mail address" -msgstr "" - -#: paperless_mail/models.py:111 -msgid "Use name (or mail address if not available)" -msgstr "" - -#: paperless_mail/models.py:113 -msgid "Use correspondent selected below" -msgstr "" - -#: paperless_mail/models.py:121 -msgid "order" -msgstr "" - -#: paperless_mail/models.py:128 -msgid "account" -msgstr "" - -#: paperless_mail/models.py:132 -msgid "folder" -msgstr "" - -#: paperless_mail/models.py:134 -msgid "Subfolders must be separated by dots." -msgstr "" - -#: paperless_mail/models.py:138 -msgid "filter from" -msgstr "" - -#: paperless_mail/models.py:141 -msgid "filter subject" -msgstr "" - -#: paperless_mail/models.py:144 -msgid "filter body" -msgstr "" - -#: paperless_mail/models.py:148 -msgid "filter attachment filename" -msgstr "" - -#: paperless_mail/models.py:150 -msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." -msgstr "" - -#: paperless_mail/models.py:156 -msgid "maximum age" -msgstr "" - -#: paperless_mail/models.py:158 -msgid "Specified in days." -msgstr "" - -#: paperless_mail/models.py:161 -msgid "attachment type" -msgstr "" - -#: paperless_mail/models.py:164 -msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter." -msgstr "" - -#: paperless_mail/models.py:169 -msgid "action" -msgstr "" - -#: paperless_mail/models.py:175 -msgid "action parameter" -msgstr "" - -#: paperless_mail/models.py:177 -msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action. Subfolders must be separated by dots." -msgstr "" - -#: paperless_mail/models.py:184 -msgid "assign title from" -msgstr "" - -#: paperless_mail/models.py:194 -msgid "assign this tag" -msgstr "" - -#: paperless_mail/models.py:202 -msgid "assign this document type" -msgstr "" - -#: paperless_mail/models.py:206 -msgid "assign correspondent from" -msgstr "" - -#: paperless_mail/models.py:216 -msgid "assign this correspondent" -msgstr "" - diff --git a/src/locale/ar_EG/LC_MESSAGES/django.po b/src/locale/ar_EG/LC_MESSAGES/django.po deleted file mode 100644 index cef7ec06f..000000000 --- a/src/locale/ar_EG/LC_MESSAGES/django.po +++ /dev/null @@ -1,698 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: paperless-ng\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-16 09:38+0000\n" -"PO-Revision-Date: 2021-11-23 18:07\n" -"Last-Translator: \n" -"Language-Team: Arabic, Egypt\n" -"Language: ar_EG\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n" -"X-Crowdin-Project: paperless-ng\n" -"X-Crowdin-Project-ID: 434940\n" -"X-Crowdin-Language: ar-EG\n" -"X-Crowdin-File: /dev/src/locale/en_US/LC_MESSAGES/django.po\n" -"X-Crowdin-File-ID: 54\n" - -#: documents/apps.py:10 -msgid "Documents" -msgstr "" - -#: documents/models.py:32 -msgid "Any word" -msgstr "" - -#: documents/models.py:33 -msgid "All words" -msgstr "" - -#: documents/models.py:34 -msgid "Exact match" -msgstr "" - -#: documents/models.py:35 -msgid "Regular expression" -msgstr "" - -#: documents/models.py:36 -msgid "Fuzzy word" -msgstr "" - -#: documents/models.py:37 -msgid "Automatic" -msgstr "" - -#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25 -#: paperless_mail/models.py:117 -msgid "name" -msgstr "" - -#: documents/models.py:45 -msgid "match" -msgstr "" - -#: documents/models.py:49 -msgid "matching algorithm" -msgstr "" - -#: documents/models.py:55 -msgid "is insensitive" -msgstr "" - -#: documents/models.py:74 documents/models.py:120 -msgid "correspondent" -msgstr "" - -#: documents/models.py:75 -msgid "correspondents" -msgstr "" - -#: documents/models.py:81 -msgid "color" -msgstr "" - -#: documents/models.py:87 -msgid "is inbox tag" -msgstr "" - -#: documents/models.py:89 -msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." -msgstr "" - -#: documents/models.py:94 -msgid "tag" -msgstr "" - -#: documents/models.py:95 documents/models.py:151 -msgid "tags" -msgstr "" - -#: documents/models.py:101 documents/models.py:133 -msgid "document type" -msgstr "" - -#: documents/models.py:102 -msgid "document types" -msgstr "" - -#: documents/models.py:110 -msgid "Unencrypted" -msgstr "" - -#: documents/models.py:111 -msgid "Encrypted with GNU Privacy Guard" -msgstr "" - -#: documents/models.py:124 -msgid "title" -msgstr "" - -#: documents/models.py:137 -msgid "content" -msgstr "" - -#: documents/models.py:139 -msgid "The raw, text-only data of the document. This field is primarily used for searching." -msgstr "" - -#: documents/models.py:144 -msgid "mime type" -msgstr "" - -#: documents/models.py:155 -msgid "checksum" -msgstr "" - -#: documents/models.py:159 -msgid "The checksum of the original document." -msgstr "" - -#: documents/models.py:163 -msgid "archive checksum" -msgstr "" - -#: documents/models.py:168 -msgid "The checksum of the archived document." -msgstr "" - -#: documents/models.py:172 documents/models.py:328 -msgid "created" -msgstr "" - -#: documents/models.py:176 -msgid "modified" -msgstr "" - -#: documents/models.py:180 -msgid "storage type" -msgstr "" - -#: documents/models.py:188 -msgid "added" -msgstr "" - -#: documents/models.py:192 -msgid "filename" -msgstr "" - -#: documents/models.py:198 -msgid "Current filename in storage" -msgstr "" - -#: documents/models.py:202 -msgid "archive filename" -msgstr "" - -#: documents/models.py:208 -msgid "Current archive filename in storage" -msgstr "" - -#: documents/models.py:212 -msgid "archive serial number" -msgstr "" - -#: documents/models.py:217 -msgid "The position of this document in your physical document archive." -msgstr "" - -#: documents/models.py:223 -msgid "document" -msgstr "" - -#: documents/models.py:224 -msgid "documents" -msgstr "" - -#: documents/models.py:311 -msgid "debug" -msgstr "" - -#: documents/models.py:312 -msgid "information" -msgstr "" - -#: documents/models.py:313 -msgid "warning" -msgstr "" - -#: documents/models.py:314 -msgid "error" -msgstr "" - -#: documents/models.py:315 -msgid "critical" -msgstr "" - -#: documents/models.py:319 -msgid "group" -msgstr "" - -#: documents/models.py:322 -msgid "message" -msgstr "" - -#: documents/models.py:325 -msgid "level" -msgstr "" - -#: documents/models.py:332 -msgid "log" -msgstr "" - -#: documents/models.py:333 -msgid "logs" -msgstr "" - -#: documents/models.py:344 documents/models.py:401 -msgid "saved view" -msgstr "" - -#: documents/models.py:345 -msgid "saved views" -msgstr "" - -#: documents/models.py:348 -msgid "user" -msgstr "" - -#: documents/models.py:354 -msgid "show on dashboard" -msgstr "" - -#: documents/models.py:357 -msgid "show in sidebar" -msgstr "" - -#: documents/models.py:361 -msgid "sort field" -msgstr "" - -#: documents/models.py:367 -msgid "sort reverse" -msgstr "" - -#: documents/models.py:373 -msgid "title contains" -msgstr "" - -#: documents/models.py:374 -msgid "content contains" -msgstr "" - -#: documents/models.py:375 -msgid "ASN is" -msgstr "" - -#: documents/models.py:376 -msgid "correspondent is" -msgstr "" - -#: documents/models.py:377 -msgid "document type is" -msgstr "" - -#: documents/models.py:378 -msgid "is in inbox" -msgstr "" - -#: documents/models.py:379 -msgid "has tag" -msgstr "" - -#: documents/models.py:380 -msgid "has any tag" -msgstr "" - -#: documents/models.py:381 -msgid "created before" -msgstr "" - -#: documents/models.py:382 -msgid "created after" -msgstr "" - -#: documents/models.py:383 -msgid "created year is" -msgstr "" - -#: documents/models.py:384 -msgid "created month is" -msgstr "" - -#: documents/models.py:385 -msgid "created day is" -msgstr "" - -#: documents/models.py:386 -msgid "added before" -msgstr "" - -#: documents/models.py:387 -msgid "added after" -msgstr "" - -#: documents/models.py:388 -msgid "modified before" -msgstr "" - -#: documents/models.py:389 -msgid "modified after" -msgstr "" - -#: documents/models.py:390 -msgid "does not have tag" -msgstr "" - -#: documents/models.py:391 -msgid "does not have ASN" -msgstr "" - -#: documents/models.py:392 -msgid "title or content contains" -msgstr "" - -#: documents/models.py:393 -msgid "fulltext query" -msgstr "" - -#: documents/models.py:394 -msgid "more like this" -msgstr "" - -#: documents/models.py:405 -msgid "rule type" -msgstr "" - -#: documents/models.py:409 -msgid "value" -msgstr "" - -#: documents/models.py:415 -msgid "filter rule" -msgstr "" - -#: documents/models.py:416 -msgid "filter rules" -msgstr "" - -#: documents/serialisers.py:53 -#, python-format -msgid "Invalid regular expression: %(error)s" -msgstr "" - -#: documents/serialisers.py:177 -msgid "Invalid color." -msgstr "" - -#: documents/serialisers.py:451 -#, python-format -msgid "File type %(type)s not supported" -msgstr "" - -#: documents/templates/index.html:22 -msgid "Paperless-ng is loading..." -msgstr "" - -#: documents/templates/registration/logged_out.html:14 -msgid "Paperless-ng signed out" -msgstr "" - -#: documents/templates/registration/logged_out.html:45 -msgid "You have been successfully logged out. Bye!" -msgstr "" - -#: documents/templates/registration/logged_out.html:46 -msgid "Sign in again" -msgstr "" - -#: documents/templates/registration/login.html:15 -msgid "Paperless-ng sign in" -msgstr "" - -#: documents/templates/registration/login.html:47 -msgid "Please sign in." -msgstr "" - -#: documents/templates/registration/login.html:50 -msgid "Your username and password didn't match. Please try again." -msgstr "" - -#: documents/templates/registration/login.html:53 -msgid "Username" -msgstr "" - -#: documents/templates/registration/login.html:54 -msgid "Password" -msgstr "" - -#: documents/templates/registration/login.html:59 -msgid "Sign in" -msgstr "" - -#: paperless/settings.py:303 -msgid "English (US)" -msgstr "" - -#: paperless/settings.py:304 -msgid "English (GB)" -msgstr "" - -#: paperless/settings.py:305 -msgid "German" -msgstr "" - -#: paperless/settings.py:306 -msgid "Dutch" -msgstr "" - -#: paperless/settings.py:307 -msgid "French" -msgstr "" - -#: paperless/settings.py:308 -msgid "Portuguese (Brazil)" -msgstr "" - -#: paperless/settings.py:309 -msgid "Portuguese" -msgstr "" - -#: paperless/settings.py:310 -msgid "Italian" -msgstr "" - -#: paperless/settings.py:311 -msgid "Romanian" -msgstr "" - -#: paperless/settings.py:312 -msgid "Russian" -msgstr "" - -#: paperless/settings.py:313 -msgid "Spanish" -msgstr "" - -#: paperless/settings.py:314 -msgid "Polish" -msgstr "" - -#: paperless/settings.py:315 -msgid "Swedish" -msgstr "" - -#: paperless/urls.py:120 -msgid "Paperless-ng administration" -msgstr "" - -#: paperless_mail/admin.py:15 -msgid "Authentication" -msgstr "" - -#: paperless_mail/admin.py:18 -msgid "Advanced settings" -msgstr "" - -#: paperless_mail/admin.py:37 -msgid "Filter" -msgstr "" - -#: paperless_mail/admin.py:39 -msgid "Paperless will only process mails that match ALL of the filters given below." -msgstr "" - -#: paperless_mail/admin.py:49 -msgid "Actions" -msgstr "" - -#: paperless_mail/admin.py:51 -msgid "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched." -msgstr "" - -#: paperless_mail/admin.py:58 -msgid "Metadata" -msgstr "" - -#: paperless_mail/admin.py:60 -msgid "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined." -msgstr "" - -#: paperless_mail/apps.py:9 -msgid "Paperless mail" -msgstr "" - -#: paperless_mail/models.py:11 -msgid "mail account" -msgstr "" - -#: paperless_mail/models.py:12 -msgid "mail accounts" -msgstr "" - -#: paperless_mail/models.py:19 -msgid "No encryption" -msgstr "" - -#: paperless_mail/models.py:20 -msgid "Use SSL" -msgstr "" - -#: paperless_mail/models.py:21 -msgid "Use STARTTLS" -msgstr "" - -#: paperless_mail/models.py:29 -msgid "IMAP server" -msgstr "" - -#: paperless_mail/models.py:33 -msgid "IMAP port" -msgstr "" - -#: paperless_mail/models.py:36 -msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections." -msgstr "" - -#: paperless_mail/models.py:40 -msgid "IMAP security" -msgstr "" - -#: paperless_mail/models.py:46 -msgid "username" -msgstr "" - -#: paperless_mail/models.py:50 -msgid "password" -msgstr "" - -#: paperless_mail/models.py:54 -msgid "character set" -msgstr "" - -#: paperless_mail/models.py:57 -msgid "The character set to use when communicating with the mail server, such as 'UTF-8' or 'US-ASCII'." -msgstr "" - -#: paperless_mail/models.py:68 -msgid "mail rule" -msgstr "" - -#: paperless_mail/models.py:69 -msgid "mail rules" -msgstr "" - -#: paperless_mail/models.py:75 -msgid "Only process attachments." -msgstr "" - -#: paperless_mail/models.py:76 -msgid "Process all files, including 'inline' attachments." -msgstr "" - -#: paperless_mail/models.py:86 -msgid "Mark as read, don't process read mails" -msgstr "" - -#: paperless_mail/models.py:87 -msgid "Flag the mail, don't process flagged mails" -msgstr "" - -#: paperless_mail/models.py:88 -msgid "Move to specified folder" -msgstr "" - -#: paperless_mail/models.py:89 -msgid "Delete" -msgstr "" - -#: paperless_mail/models.py:96 -msgid "Use subject as title" -msgstr "" - -#: paperless_mail/models.py:97 -msgid "Use attachment filename as title" -msgstr "" - -#: paperless_mail/models.py:107 -msgid "Do not assign a correspondent" -msgstr "" - -#: paperless_mail/models.py:109 -msgid "Use mail address" -msgstr "" - -#: paperless_mail/models.py:111 -msgid "Use name (or mail address if not available)" -msgstr "" - -#: paperless_mail/models.py:113 -msgid "Use correspondent selected below" -msgstr "" - -#: paperless_mail/models.py:121 -msgid "order" -msgstr "" - -#: paperless_mail/models.py:128 -msgid "account" -msgstr "" - -#: paperless_mail/models.py:132 -msgid "folder" -msgstr "" - -#: paperless_mail/models.py:134 -msgid "Subfolders must be separated by dots." -msgstr "" - -#: paperless_mail/models.py:138 -msgid "filter from" -msgstr "" - -#: paperless_mail/models.py:141 -msgid "filter subject" -msgstr "" - -#: paperless_mail/models.py:144 -msgid "filter body" -msgstr "" - -#: paperless_mail/models.py:148 -msgid "filter attachment filename" -msgstr "" - -#: paperless_mail/models.py:150 -msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." -msgstr "" - -#: paperless_mail/models.py:156 -msgid "maximum age" -msgstr "" - -#: paperless_mail/models.py:158 -msgid "Specified in days." -msgstr "" - -#: paperless_mail/models.py:161 -msgid "attachment type" -msgstr "" - -#: paperless_mail/models.py:164 -msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter." -msgstr "" - -#: paperless_mail/models.py:169 -msgid "action" -msgstr "" - -#: paperless_mail/models.py:175 -msgid "action parameter" -msgstr "" - -#: paperless_mail/models.py:177 -msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action. Subfolders must be separated by dots." -msgstr "" - -#: paperless_mail/models.py:184 -msgid "assign title from" -msgstr "" - -#: paperless_mail/models.py:194 -msgid "assign this tag" -msgstr "" - -#: paperless_mail/models.py:202 -msgid "assign this document type" -msgstr "" - -#: paperless_mail/models.py:206 -msgid "assign correspondent from" -msgstr "" - -#: paperless_mail/models.py:216 -msgid "assign this correspondent" -msgstr "" - diff --git a/src/locale/ar_YE/LC_MESSAGES/django.po b/src/locale/ar_YE/LC_MESSAGES/django.po deleted file mode 100644 index 397544884..000000000 --- a/src/locale/ar_YE/LC_MESSAGES/django.po +++ /dev/null @@ -1,698 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: paperless-ng\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-16 09:38+0000\n" -"PO-Revision-Date: 2021-11-23 18:07\n" -"Last-Translator: \n" -"Language-Team: Arabic, Yemen\n" -"Language: ar_YE\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n" -"X-Crowdin-Project: paperless-ng\n" -"X-Crowdin-Project-ID: 434940\n" -"X-Crowdin-Language: ar-YE\n" -"X-Crowdin-File: /dev/src/locale/en_US/LC_MESSAGES/django.po\n" -"X-Crowdin-File-ID: 54\n" - -#: documents/apps.py:10 -msgid "Documents" -msgstr "" - -#: documents/models.py:32 -msgid "Any word" -msgstr "" - -#: documents/models.py:33 -msgid "All words" -msgstr "" - -#: documents/models.py:34 -msgid "Exact match" -msgstr "" - -#: documents/models.py:35 -msgid "Regular expression" -msgstr "" - -#: documents/models.py:36 -msgid "Fuzzy word" -msgstr "" - -#: documents/models.py:37 -msgid "Automatic" -msgstr "" - -#: documents/models.py:41 documents/models.py:350 paperless_mail/models.py:25 -#: paperless_mail/models.py:117 -msgid "name" -msgstr "" - -#: documents/models.py:45 -msgid "match" -msgstr "" - -#: documents/models.py:49 -msgid "matching algorithm" -msgstr "" - -#: documents/models.py:55 -msgid "is insensitive" -msgstr "" - -#: documents/models.py:74 documents/models.py:120 -msgid "correspondent" -msgstr "" - -#: documents/models.py:75 -msgid "correspondents" -msgstr "" - -#: documents/models.py:81 -msgid "color" -msgstr "" - -#: documents/models.py:87 -msgid "is inbox tag" -msgstr "" - -#: documents/models.py:89 -msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." -msgstr "" - -#: documents/models.py:94 -msgid "tag" -msgstr "" - -#: documents/models.py:95 documents/models.py:151 -msgid "tags" -msgstr "" - -#: documents/models.py:101 documents/models.py:133 -msgid "document type" -msgstr "" - -#: documents/models.py:102 -msgid "document types" -msgstr "" - -#: documents/models.py:110 -msgid "Unencrypted" -msgstr "" - -#: documents/models.py:111 -msgid "Encrypted with GNU Privacy Guard" -msgstr "" - -#: documents/models.py:124 -msgid "title" -msgstr "" - -#: documents/models.py:137 -msgid "content" -msgstr "" - -#: documents/models.py:139 -msgid "The raw, text-only data of the document. This field is primarily used for searching." -msgstr "" - -#: documents/models.py:144 -msgid "mime type" -msgstr "" - -#: documents/models.py:155 -msgid "checksum" -msgstr "" - -#: documents/models.py:159 -msgid "The checksum of the original document." -msgstr "" - -#: documents/models.py:163 -msgid "archive checksum" -msgstr "" - -#: documents/models.py:168 -msgid "The checksum of the archived document." -msgstr "" - -#: documents/models.py:172 documents/models.py:328 -msgid "created" -msgstr "" - -#: documents/models.py:176 -msgid "modified" -msgstr "" - -#: documents/models.py:180 -msgid "storage type" -msgstr "" - -#: documents/models.py:188 -msgid "added" -msgstr "" - -#: documents/models.py:192 -msgid "filename" -msgstr "" - -#: documents/models.py:198 -msgid "Current filename in storage" -msgstr "" - -#: documents/models.py:202 -msgid "archive filename" -msgstr "" - -#: documents/models.py:208 -msgid "Current archive filename in storage" -msgstr "" - -#: documents/models.py:212 -msgid "archive serial number" -msgstr "" - -#: documents/models.py:217 -msgid "The position of this document in your physical document archive." -msgstr "" - -#: documents/models.py:223 -msgid "document" -msgstr "" - -#: documents/models.py:224 -msgid "documents" -msgstr "" - -#: documents/models.py:311 -msgid "debug" -msgstr "" - -#: documents/models.py:312 -msgid "information" -msgstr "" - -#: documents/models.py:313 -msgid "warning" -msgstr "" - -#: documents/models.py:314 -msgid "error" -msgstr "" - -#: documents/models.py:315 -msgid "critical" -msgstr "" - -#: documents/models.py:319 -msgid "group" -msgstr "" - -#: documents/models.py:322 -msgid "message" -msgstr "" - -#: documents/models.py:325 -msgid "level" -msgstr "" - -#: documents/models.py:332 -msgid "log" -msgstr "" - -#: documents/models.py:333 -msgid "logs" -msgstr "" - -#: documents/models.py:344 documents/models.py:401 -msgid "saved view" -msgstr "" - -#: documents/models.py:345 -msgid "saved views" -msgstr "" - -#: documents/models.py:348 -msgid "user" -msgstr "" - -#: documents/models.py:354 -msgid "show on dashboard" -msgstr "" - -#: documents/models.py:357 -msgid "show in sidebar" -msgstr "" - -#: documents/models.py:361 -msgid "sort field" -msgstr "" - -#: documents/models.py:367 -msgid "sort reverse" -msgstr "" - -#: documents/models.py:373 -msgid "title contains" -msgstr "" - -#: documents/models.py:374 -msgid "content contains" -msgstr "" - -#: documents/models.py:375 -msgid "ASN is" -msgstr "" - -#: documents/models.py:376 -msgid "correspondent is" -msgstr "" - -#: documents/models.py:377 -msgid "document type is" -msgstr "" - -#: documents/models.py:378 -msgid "is in inbox" -msgstr "" - -#: documents/models.py:379 -msgid "has tag" -msgstr "" - -#: documents/models.py:380 -msgid "has any tag" -msgstr "" - -#: documents/models.py:381 -msgid "created before" -msgstr "" - -#: documents/models.py:382 -msgid "created after" -msgstr "" - -#: documents/models.py:383 -msgid "created year is" -msgstr "" - -#: documents/models.py:384 -msgid "created month is" -msgstr "" - -#: documents/models.py:385 -msgid "created day is" -msgstr "" - -#: documents/models.py:386 -msgid "added before" -msgstr "" - -#: documents/models.py:387 -msgid "added after" -msgstr "" - -#: documents/models.py:388 -msgid "modified before" -msgstr "" - -#: documents/models.py:389 -msgid "modified after" -msgstr "" - -#: documents/models.py:390 -msgid "does not have tag" -msgstr "" - -#: documents/models.py:391 -msgid "does not have ASN" -msgstr "" - -#: documents/models.py:392 -msgid "title or content contains" -msgstr "" - -#: documents/models.py:393 -msgid "fulltext query" -msgstr "" - -#: documents/models.py:394 -msgid "more like this" -msgstr "" - -#: documents/models.py:405 -msgid "rule type" -msgstr "" - -#: documents/models.py:409 -msgid "value" -msgstr "" - -#: documents/models.py:415 -msgid "filter rule" -msgstr "" - -#: documents/models.py:416 -msgid "filter rules" -msgstr "" - -#: documents/serialisers.py:53 -#, python-format -msgid "Invalid regular expression: %(error)s" -msgstr "" - -#: documents/serialisers.py:177 -msgid "Invalid color." -msgstr "" - -#: documents/serialisers.py:451 -#, python-format -msgid "File type %(type)s not supported" -msgstr "" - -#: documents/templates/index.html:22 -msgid "Paperless-ng is loading..." -msgstr "" - -#: documents/templates/registration/logged_out.html:14 -msgid "Paperless-ng signed out" -msgstr "" - -#: documents/templates/registration/logged_out.html:45 -msgid "You have been successfully logged out. Bye!" -msgstr "" - -#: documents/templates/registration/logged_out.html:46 -msgid "Sign in again" -msgstr "" - -#: documents/templates/registration/login.html:15 -msgid "Paperless-ng sign in" -msgstr "" - -#: documents/templates/registration/login.html:47 -msgid "Please sign in." -msgstr "" - -#: documents/templates/registration/login.html:50 -msgid "Your username and password didn't match. Please try again." -msgstr "" - -#: documents/templates/registration/login.html:53 -msgid "Username" -msgstr "" - -#: documents/templates/registration/login.html:54 -msgid "Password" -msgstr "" - -#: documents/templates/registration/login.html:59 -msgid "Sign in" -msgstr "" - -#: paperless/settings.py:303 -msgid "English (US)" -msgstr "" - -#: paperless/settings.py:304 -msgid "English (GB)" -msgstr "" - -#: paperless/settings.py:305 -msgid "German" -msgstr "" - -#: paperless/settings.py:306 -msgid "Dutch" -msgstr "" - -#: paperless/settings.py:307 -msgid "French" -msgstr "" - -#: paperless/settings.py:308 -msgid "Portuguese (Brazil)" -msgstr "" - -#: paperless/settings.py:309 -msgid "Portuguese" -msgstr "" - -#: paperless/settings.py:310 -msgid "Italian" -msgstr "" - -#: paperless/settings.py:311 -msgid "Romanian" -msgstr "" - -#: paperless/settings.py:312 -msgid "Russian" -msgstr "" - -#: paperless/settings.py:313 -msgid "Spanish" -msgstr "" - -#: paperless/settings.py:314 -msgid "Polish" -msgstr "" - -#: paperless/settings.py:315 -msgid "Swedish" -msgstr "" - -#: paperless/urls.py:120 -msgid "Paperless-ng administration" -msgstr "" - -#: paperless_mail/admin.py:15 -msgid "Authentication" -msgstr "" - -#: paperless_mail/admin.py:18 -msgid "Advanced settings" -msgstr "" - -#: paperless_mail/admin.py:37 -msgid "Filter" -msgstr "" - -#: paperless_mail/admin.py:39 -msgid "Paperless will only process mails that match ALL of the filters given below." -msgstr "" - -#: paperless_mail/admin.py:49 -msgid "Actions" -msgstr "" - -#: paperless_mail/admin.py:51 -msgid "The action applied to the mail. This action is only performed when documents were consumed from the mail. Mails without attachments will remain entirely untouched." -msgstr "" - -#: paperless_mail/admin.py:58 -msgid "Metadata" -msgstr "" - -#: paperless_mail/admin.py:60 -msgid "Assign metadata to documents consumed from this rule automatically. If you do not assign tags, types or correspondents here, paperless will still process all matching rules that you have defined." -msgstr "" - -#: paperless_mail/apps.py:9 -msgid "Paperless mail" -msgstr "" - -#: paperless_mail/models.py:11 -msgid "mail account" -msgstr "" - -#: paperless_mail/models.py:12 -msgid "mail accounts" -msgstr "" - -#: paperless_mail/models.py:19 -msgid "No encryption" -msgstr "" - -#: paperless_mail/models.py:20 -msgid "Use SSL" -msgstr "" - -#: paperless_mail/models.py:21 -msgid "Use STARTTLS" -msgstr "" - -#: paperless_mail/models.py:29 -msgid "IMAP server" -msgstr "" - -#: paperless_mail/models.py:33 -msgid "IMAP port" -msgstr "" - -#: paperless_mail/models.py:36 -msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections." -msgstr "" - -#: paperless_mail/models.py:40 -msgid "IMAP security" -msgstr "" - -#: paperless_mail/models.py:46 -msgid "username" -msgstr "" - -#: paperless_mail/models.py:50 -msgid "password" -msgstr "" - -#: paperless_mail/models.py:54 -msgid "character set" -msgstr "" - -#: paperless_mail/models.py:57 -msgid "The character set to use when communicating with the mail server, such as 'UTF-8' or 'US-ASCII'." -msgstr "" - -#: paperless_mail/models.py:68 -msgid "mail rule" -msgstr "" - -#: paperless_mail/models.py:69 -msgid "mail rules" -msgstr "" - -#: paperless_mail/models.py:75 -msgid "Only process attachments." -msgstr "" - -#: paperless_mail/models.py:76 -msgid "Process all files, including 'inline' attachments." -msgstr "" - -#: paperless_mail/models.py:86 -msgid "Mark as read, don't process read mails" -msgstr "" - -#: paperless_mail/models.py:87 -msgid "Flag the mail, don't process flagged mails" -msgstr "" - -#: paperless_mail/models.py:88 -msgid "Move to specified folder" -msgstr "" - -#: paperless_mail/models.py:89 -msgid "Delete" -msgstr "" - -#: paperless_mail/models.py:96 -msgid "Use subject as title" -msgstr "" - -#: paperless_mail/models.py:97 -msgid "Use attachment filename as title" -msgstr "" - -#: paperless_mail/models.py:107 -msgid "Do not assign a correspondent" -msgstr "" - -#: paperless_mail/models.py:109 -msgid "Use mail address" -msgstr "" - -#: paperless_mail/models.py:111 -msgid "Use name (or mail address if not available)" -msgstr "" - -#: paperless_mail/models.py:113 -msgid "Use correspondent selected below" -msgstr "" - -#: paperless_mail/models.py:121 -msgid "order" -msgstr "" - -#: paperless_mail/models.py:128 -msgid "account" -msgstr "" - -#: paperless_mail/models.py:132 -msgid "folder" -msgstr "" - -#: paperless_mail/models.py:134 -msgid "Subfolders must be separated by dots." -msgstr "" - -#: paperless_mail/models.py:138 -msgid "filter from" -msgstr "" - -#: paperless_mail/models.py:141 -msgid "filter subject" -msgstr "" - -#: paperless_mail/models.py:144 -msgid "filter body" -msgstr "" - -#: paperless_mail/models.py:148 -msgid "filter attachment filename" -msgstr "" - -#: paperless_mail/models.py:150 -msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." -msgstr "" - -#: paperless_mail/models.py:156 -msgid "maximum age" -msgstr "" - -#: paperless_mail/models.py:158 -msgid "Specified in days." -msgstr "" - -#: paperless_mail/models.py:161 -msgid "attachment type" -msgstr "" - -#: paperless_mail/models.py:164 -msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter." -msgstr "" - -#: paperless_mail/models.py:169 -msgid "action" -msgstr "" - -#: paperless_mail/models.py:175 -msgid "action parameter" -msgstr "" - -#: paperless_mail/models.py:177 -msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action. Subfolders must be separated by dots." -msgstr "" - -#: paperless_mail/models.py:184 -msgid "assign title from" -msgstr "" - -#: paperless_mail/models.py:194 -msgid "assign this tag" -msgstr "" - -#: paperless_mail/models.py:202 -msgid "assign this document type" -msgstr "" - -#: paperless_mail/models.py:206 -msgid "assign correspondent from" -msgstr "" - -#: paperless_mail/models.py:216 -msgid "assign this correspondent" -msgstr "" - diff --git a/src/locale/be_BY/LC_MESSAGES/django.po b/src/locale/be_BY/LC_MESSAGES/django.po index 14d3591d2..2b12b7dfb 100644 --- a/src/locale/be_BY/LC_MESSAGES/django.po +++ b/src/locale/be_BY/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-10-16 13:46\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Belarusian\n" "Language: be_BY\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Дакументы" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Любое слова" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Усе словы" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Дакладнае супадзенне" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Рэгулярны выраз" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Невыразнае слова" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Аўтаматычна" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "назва" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "супадзенне" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "алгарытм супастаўлення" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "без уліку рэгістра" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "карэспандэнт" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "карэспандэнты" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "колер" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "гэта ўваходны тэг" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Пазначыць гэты тэг як тэг папкі \"Уваходныя\": Усе нядаўна спажытыя дакументы будуць пазначаны тэгамі \"Уваходныя\"." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "тэг" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "тэгі" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "тып дакумента" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "тыпы дакументаў" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "шлях" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "шлях захоўвання" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "шляхі захоўвання" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Незашыфраваны" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Зашыфравана з дапамогай GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "назва" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "змест" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Неапрацаваныя тэкставыя даныя дакумента. Гэта поле ў асноўным выкарыстоўваецца для пошуку." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "тып MIME" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "кантрольная сума" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Кантрольная сума зыходнага дакумента." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "кантрольная сума архіва" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Кантрольная сума архіўнага дакумента." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "створаны" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "мадыфікаваны" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "тып захоўвання" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "дададзена" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "імя файла" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Цяперашняе імя файла ў сховішчы" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "імя файла архіва" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Цяперашняе імя файла архіва ў сховішчы" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "парадкавы нумар архіва" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Пазіцыя гэтага дакумента ў вашым фізічным архіве дакументаў." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "дакумент" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "дакументы" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "адладка" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "інфармацыя" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "папярэджанне" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "памылка" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "крытычны" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "група" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "паведамленне" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "узровень" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "лог" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "логі" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "захаваны выгляд" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "захаваныя выгляды" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "карыстальнік" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "паказаць на панэлі" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "паказаць у бакавой панэлі" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "поле сартавання" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "сартаваць у адваротным парадку" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "назва змяшчае" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "змест змяшчае" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "карэспандэнт" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "тып дакумента" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "ва ўваходных" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "мае тэг" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "мае любы тэг" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "створана перад" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "створана пасля" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "год стварэння" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "месяц стварэння" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "дзень стварэння" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "даданы перад" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "даданы пасля" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "зменены перад" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "зменены пасля" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "не мае тэга" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "не мае ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "назва або змест смяшчае" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "поўнатэкставы запыт" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "больш падобнага" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "мае тэгі ў" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "тып правіла" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "значэнне" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "правіла фільтрацыі" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "правілы фільтрацыі" -#: documents/models.py:521 -msgid "started" -msgstr "пачата" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Няправільны рэгулярны выраз: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Няправільны колер." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Тып файла %(type)s не падтрымліваецца" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Выяўлена няправільная зменная." @@ -444,87 +556,87 @@ msgstr "Пароль" msgid "Sign in" msgstr "Увайсці" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Англійская (ЗША)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Беларуская" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Чэшская" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Дацкая" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Нямецкая" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Англійская (Вялікабрытанія)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Іспанская" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Французская" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Італьянская" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Люксембургская" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Нідэрландская" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Польская" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Партугальская (Бразілія)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Партугальская" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Румынская" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Руская" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Славенская" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Сербская" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Шведская" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Турэцкая" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Кітайская спрошчаная" diff --git a/src/locale/cs_CZ/LC_MESSAGES/django.po b/src/locale/cs_CZ/LC_MESSAGES/django.po index fc6dd3ede..2acdedcb5 100644 --- a/src/locale/cs_CZ/LC_MESSAGES/django.po +++ b/src/locale/cs_CZ/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-10-18 20:06\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Czech\n" "Language: cs_CZ\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumenty" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Jakékoliv slovo" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Všechna slova" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Přesná shoda" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Regulární výraz" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Fuzzy slovo" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatický" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "název" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "shoda" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algoritmus pro shodu" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "je ignorováno" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "korespondent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "korespondenti" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "barva" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "tag přichozí" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Označí tento tag jako tag pro příchozí: Všechny nově zkonzumované dokumenty budou označeny tagem pro přichozí" -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "tagy" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "tagy" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "typ dokumentu" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "typy dokumentu" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "cesta" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "cesta k úložišti" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "cesta k úložišti" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Nešifrované" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Šifrované pomocí GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "titulek" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "obsah" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Nezpracovaná, pouze textová data dokumentu. Toto pole je používáno především pro vyhledávání." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "mime typ" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "kontrolní součet" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Kontrolní součet původního dokumentu" -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "kontrolní součet archivu" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Kontrolní součet archivovaného dokumentu." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "vytvořeno" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "upraveno" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "typ úložiště" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "přidáno" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "název souboru" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Aktuální název souboru v úložišti" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "Název archivovaného souboru" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Aktuální název souboru archivu v úložišti" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "sériové číslo archivu" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Pozice dokumentu ve vašem archivu fyzických dokumentů" -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "dokumenty" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "ladění" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informace" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "varování" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "chyba" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritická" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "skupina" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "zpráva" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "úroveň" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "záznam" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "záznamy" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "uložený pohled" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "uložené pohledy" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "uživatel" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "zobrazit v dashboardu" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "zobrazit v postranním menu" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "pole na řazení" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "třídit opačně" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "titulek obsahuje" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "obsah obsahuje" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN je" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "korespondent je" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "typ dokumentu je" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "je v příchozích" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "má tag" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "má jakýkoliv tag" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "vytvořeno před" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "vytvořeno po" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "rok vytvoření je" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "měsíc vytvoření je" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "den vytvoření je" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "přidáno před" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "přidáno po" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "upraveno před" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "upraveno po" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "nemá tag" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "Nemá ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "Titulek nebo obsah obsahuje" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "Fulltextový dotaz" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "Podobné" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "má značky v" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "typ pravidla" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "hodnota" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "filtrovací pravidlo" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "filtrovací pravidla" -#: documents/models.py:521 -msgid "started" -msgstr "zahájeno" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Neplatný regulární výraz: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Neplatná barva." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Typ souboru %(type)s není podporován" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Zjištěna neplatná proměnná." @@ -444,87 +556,87 @@ msgstr "Heslo" msgid "Sign in" msgstr "Přihlásit se" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Angličtina (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Běloruština" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Čeština" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Dánština" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Němčina" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Angličtina (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Španělština" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Francouzština" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italština" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Lucemburština" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Holandština" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polština" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugalština (Brazílie)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugalština" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumunština" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Ruština" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slovinština" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Srbština" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Švédština" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turečtina" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Čínština (zjednodušená)" diff --git a/src/locale/da_DK/LC_MESSAGES/django.po b/src/locale/da_DK/LC_MESSAGES/django.po index 2fd63c6f5..f7ccff0db 100644 --- a/src/locale/da_DK/LC_MESSAGES/django.po +++ b/src/locale/da_DK/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-08 22:07\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Danish\n" "Language: da_DK\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumenter" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Ethvert ord" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Alle ord" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Præcis match" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Regulær udtryk" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Tilnærmet ord" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatisk" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "navn" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "match" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "matching algoritme" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "er usensitiv" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "korrespondent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "korrespondenter" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "farve" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "er indbakkeetiket" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Markerer denne etiket som en indbakkeetiket: Alle ny-bearbejdede dokumenter vil blive mærket med indbakkeetiketter." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "etiket" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "etiketter" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "dokumenttype" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "dokumenttyper" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Ukrypteret" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Krypteret med GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "titel" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "indhold" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Dokumentets rå tekstdata. Dette felt bruges primært til søgning." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "MIME-type" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "kontrolsum" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Kontrolsummen af det oprindelige dokument." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "arkiv kontrolsum" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Kontrolsummen af det arkiverede dokument." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "oprettet" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "ændret" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "lagringstype" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "tilføjet" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "filnavn" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Nuværende filnavn lagret" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "arkiv filnavn" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Nuværende arkivfilnavn lagret" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "arkiv serienummer" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Placeringen af dette dokument i dit fysiske dokumentarkiv." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "dokumenter" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "fejlfinding" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "information" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "advarsel" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "fejl" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritisk" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "gruppe" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "besked" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "niveau" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "log" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "logninger" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "gemt visning" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "gemte visninger" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "bruger" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "vis på betjeningspanel" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "vis i sidepanelet" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "sortér felt" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "sortér omvendt" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "titel indeholder" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "indhold indeholder" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN er" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "korrespondent er" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "dokumenttype er" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "er i indbakke" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "har etiket" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "har en etiket" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "oprettet før" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "oprettet efter" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "oprettet år er" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "oprettet måned er" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "oprettet dag er" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "tilføjet før" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "tilføjet efter" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "ændret før" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "ændret efter" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "har ikke nogen etiket" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "har ikke ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "titel eller indhold indeholder" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "fuldtekst forespørgsel" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "mere som dette" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "har etiketter i" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "regeltype" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "værdi" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "filtreringsregel" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "filtreringsregler" -#: documents/models.py:521 -msgid "started" +#: documents/models.py:536 +msgid "Task ID" msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Ugyldigt regulært udtryk: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Ugyldig farve." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Filtype %(type)s understøttes ikke" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "" @@ -444,87 +556,87 @@ msgstr "Adgangskode" msgid "Sign in" msgstr "Log ind" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Engelsk (USA)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Tjekkisk" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Dansk" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Tysk" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Engelsk (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Spansk" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Fransk" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italiensk" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxemburgsk" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Hollandsk" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polsk" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugisisk (Brasilien)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugisisk" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Romansk" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Russisk" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Svensk" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "" diff --git a/src/locale/de_DE/LC_MESSAGES/django.po b/src/locale/de_DE/LC_MESSAGES/django.po index e61bcb564..446ff9672 100644 --- a/src/locale/de_DE/LC_MESSAGES/django.po +++ b/src/locale/de_DE/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-09-04 11:44\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-26 20:28\n" "Last-Translator: \n" "Language-Team: German\n" "Language: de_DE\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumente" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Irgendein Wort" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Alle Wörter" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Exakte Übereinstimmung" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Regulärer Ausdruck" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Ungenaues Wort" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatisch" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "Name" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "Zuweisungsmuster" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "Zuweisungsalgorithmus" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "Groß-/Kleinschreibung irrelevant" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "Korrespondent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "Korrespondenten" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "Farbe" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "Posteingangs-Tag" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Markiert das Tag als Posteingangs-Tag. Neue Dokumente werden immer mit diesem Tag versehen." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "Tag" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "Tags" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "Dokumenttyp" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "Dokumenttypen" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "Pfad" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "Speicherpfad" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "Speicherpfade" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Nicht verschlüsselt" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Durch GNU Privacy Guard verschlüsselt" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "Titel" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "Inhalt" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Der Inhalt des Dokuments in Textform. Dieses Feld wird primär für die Suche verwendet." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "MIME-Typ" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "Prüfsumme" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Die Prüfsumme des originalen Dokuments." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "Archiv-Prüfsumme" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Die Prüfsumme des archivierten Dokuments." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "Erstellt" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "Geändert" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "Speichertyp" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "Hinzugefügt" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "Dateiname" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Aktueller Dateiname im Datenspeicher" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "Archiv-Dateiname" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Aktueller Dateiname im Archiv" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "Original-Dateiname" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "Der Originalname der Datei beim Hochladen" + +#: documents/models.py:231 msgid "archive serial number" msgstr "Archiv-Seriennummer" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Die Position dieses Dokuments in Ihrem physischen Dokumentenarchiv." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "Dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "Dokumente" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "Debug" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "Information" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "Warnung" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "Fehler" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "Kritisch" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "Gruppe" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "Nachricht" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "Level" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "Protokoll" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "Protokoll" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "Gespeicherte Ansicht" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "Gespeicherte Ansichten" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "Benutzer" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "Auf Startseite zeigen" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "In Seitenleiste zeigen" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "Sortierfeld" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "Umgekehrte Sortierung" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "Titel enthält" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "Inhalt enthält" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN ist" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "Korrespondent ist" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "Dokumenttyp ist" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "Ist im Posteingang" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "Hat Tag" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "Hat irgendein Tag" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "Ausgestellt vor" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "Ausgestellt nach" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "Ausgestellt im Jahr" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "Ausgestellt im Monat" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "Ausgestellt am Tag" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "Hinzugefügt vor" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "Hinzugefügt nach" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "Geändert vor" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "Geändert nach" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "Hat nicht folgendes Tag" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "Dokument hat keine ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "Titel oder Inhalt enthält" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "Volltextsuche" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "Ähnliche Dokumente" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "hat Tags in" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "ASN größer als" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "ASN kleiner als" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "Speicherpfad ist" + +#: documents/models.py:422 msgid "rule type" msgstr "Regeltyp" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "Wert" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "Filterregel" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "Filterregeln" -#: documents/models.py:521 -msgid "started" -msgstr "gestartet" +#: documents/models.py:536 +msgid "Task ID" +msgstr "Aufgaben ID" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "Celery-ID für die ausgeführte Aufgabe" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "Bestätigt" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "Wenn die Aufgabe über das Frontend oder die API bestätigt wird" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "Aufgabenname" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "Name der Datei, für die die Aufgabe ausgeführt wurde" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "Name der ausgeführten Aufgabe" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "Aufgabe: Positionsargumente" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "JSON-Darstellung der Positionsargumente, die für die Aufgabe verwendet werden" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "Aufgabe: Benannte Argumente" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "JSON-Darstellung der benannten Argumente, die für die Aufgabe verwendet werden" + +#: documents/models.py:578 +msgid "Task State" +msgstr "Aufgabe: Status" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "Aktueller Status der laufenden Aufgabe" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "Erstellungsdatum/-zeit" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "Zeitpunkt, an dem das Ergebnis der Aufgabe erstellt wurde (in UTC)" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "Startzeitpunk" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "Zeitpunkt, als die Aufgabe erstellt wurde (in UTC)" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "Abgeschlossen Zeitpunkt" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "Zeitpunkt, an dem die Aufgabe abgeschlossen wurde (in UTC)" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "Ergebnisse" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "Die von der Aufgabe zurückgegebenen Daten" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "Kommentar zu diesem Dokument" + +#: documents/models.py:642 +msgid "comment" +msgstr "Kommentar" + +#: documents/models.py:643 +msgid "comments" +msgstr "Kommentare" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Ungültiger regulärer Ausdruck: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Ungültige Farbe." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Dateityp %(type)s nicht unterstützt" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Ungültige Variable entdeckt." @@ -444,87 +556,87 @@ msgstr "Kennwort" msgid "Sign in" msgstr "Anmelden" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Englisch (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Belarussisch" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Tschechisch" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Dänisch" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Deutsch" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Englisch (UK)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Spanisch" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Französisch" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italienisch" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxemburgisch" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Niederländisch" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polnisch" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugiesisch (Brasilien)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugiesisch" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumänisch" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Russisch" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slowenisch" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Serbisch" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Schwedisch" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Türkisch" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Vereinfachtes Chinesisch" diff --git a/src/locale/es_ES/LC_MESSAGES/django.po b/src/locale/es_ES/LC_MESSAGES/django.po index 3b565f02e..5236e3433 100644 --- a/src/locale/es_ES/LC_MESSAGES/django.po +++ b/src/locale/es_ES/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-08 22:07\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Spanish\n" "Language: es_ES\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Documentos" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Cualquier palabra" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Todas las palabras" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Coincidencia exacta" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Expresión regular" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Palabra borrosa" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automático" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "nombre" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "coincidencia" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "Algoritmo de coincidencia" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "es insensible" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "interlocutor" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "interlocutores" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "color" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "es etiqueta de bandeja" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Marca esta etiqueta como una etiqueta de bandeja: todos los documentos recién consumidos serán etiquetados con las etiquetas de bandeja." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "etiqueta" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "etiquetas" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "tipo de documento" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "tipos de documento" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "ruta" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "ruta de almacenamiento" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "rutas de almacenamiento" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Sin cifrar" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Cifrado con GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "título" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "contenido" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Los datos de texto en bruto del documento. Este campo se utiliza principalmente para las búsquedas." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "tipo MIME" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "Cadena de verificación" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "La cadena de verificación del documento original." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "cadena de comprobación del archivo" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "La cadena de verificación del documento archivado." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "creado" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "modificado" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "tipo de almacenamiento" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "añadido" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "nombre del archivo" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Nombre de archivo actual en disco" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "nombre de archivo" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Nombre de archivo actual en disco" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "número de serie del archivo" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Posición de este documento en tu archivo físico de documentos." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "documento" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "documentos" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "depuración" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "información" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "alerta" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "error" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "crítico" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "grupo" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "mensaje" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "nivel" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "log" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "logs" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "vista guardada" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "vistas guardadas" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "usuario" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "mostrar en el panel de control" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "mostrar en barra lateral" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "campo de ordenación" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "ordenar al revés" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "el título contiene" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "el contenido contiene" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN es" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "interlocutor es" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "el tipo de documento es" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "está en la bandeja de entrada" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "tiene la etiqueta" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "tiene cualquier etiqueta" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "creado antes" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "creado después" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "el año de creación es" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "el mes de creación es" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "creado el día" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "agregado antes de" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "agregado después de" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "modificado después de" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "modificado antes de" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "no tiene la etiqueta" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "no tiene ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "el título o cuerpo contiene" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "consulta de texto completo" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "más contenido similar" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "tiene etiquetas en" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "tipo de regla" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "valor" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "regla de filtrado" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "reglas de filtrado" -#: documents/models.py:521 -msgid "started" +#: documents/models.py:536 +msgid "Task ID" msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Expresión irregular inválida: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Color inválido." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Tipo de fichero %(type)s no suportado" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Variable inválida." @@ -444,87 +556,87 @@ msgstr "Contraseña" msgid "Sign in" msgstr "Iniciar sesión" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Inglés (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Bielorruso" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Checo" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Danés" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Alemán" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Inglés (Gran Bretaña)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Español" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Francés" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italiano" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxemburgués" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Alemán" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polaco" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugués (Brasil)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugués" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumano" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Ruso" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Esloveno" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Serbio" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Sueco" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turco" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Chino simplificado" diff --git a/src/locale/fi_FI/LC_MESSAGES/django.po b/src/locale/fi_FI/LC_MESSAGES/django.po index 8d817560e..0d9293cd4 100644 --- a/src/locale/fi_FI/LC_MESSAGES/django.po +++ b/src/locale/fi_FI/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-09-06 20:21\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Finnish\n" "Language: fi_FI\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumentit" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Mikä tahansa sana" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Kaikki sanat" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Tarkka osuma" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Säännöllinen lauseke (regex)" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Sumea sana" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automaattinen" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "nimi" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "osuma" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "tunnistusalgoritmi" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "ei ole herkkä" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "yhteyshenkilö" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "yhteyshenkilöt" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "väri" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "on uusien tunniste" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Merkitsee tämän tunnisteen uusien tunnisteeksi: Kaikille vastasyötetyille tiedostoille annetaan tämä tunniste." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "tunniste" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "tunnisteet" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "asiakirjatyyppi" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "asiakirjatyypit" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "polku" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "tallennustilan polku" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "tallennustilan polut" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Salaamaton" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "GNU Privacy Guard -salattu" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "otsikko" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "sisältö" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Raaka vain teksti -muotoinen dokumentin sisältö. Kenttää käytetään pääasiassa hakutoiminnossa." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "mime-tyyppi" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "tarkistussumma" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Alkuperäisen dokumentin tarkistussumma." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "arkistotarkastussumma" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Arkistoidun dokumentin tarkistussumma." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "luotu" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "muokattu" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "tallennustilan tyyppi" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "lisätty" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "tiedostonimi" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Tiedostonimi tallennustilassa" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "arkistointitiedostonimi" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Tämänhetkinen arkistointitiedostoimi tallennustilassa" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "arkistointisarjanumero" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Dokumentin sijainti fyysisessa dokumenttiarkistossa." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "dokumentti" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "dokumentit" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "virheenjäljitys" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informaatio" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "varoitus" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "virhe" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kriittinen" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "ryhmä" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "viesti" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "taso" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "loki" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "lokit" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "tallennettu näkymä" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "tallennetut näkymät" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "käyttäjä" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "näytä etusivulla" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "näytä sivupaneelissa" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "lajittelukenttä" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "lajittele käänteisesti" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "otsikko sisältää" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "sisältö sisältää" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN on" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "yhteyshenkilö on" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "dokumenttityyppi on" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "on uusi" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "on tagattu" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "on mikä tahansa tagi" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "luotu ennen" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "luotu jälkeen" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "luotu vuonna" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "luotu kuukautena" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "luomispäivä on" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "lisätty ennen" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "lisätty jälkeen" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "muokattu ennen" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "muokattu jälkeen" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "ei ole tagia" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "ei ole ASN-numeroa" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "otsikko tai sisältö sisältää" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "fulltext-kysely" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "enemmän kuten tämä" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "sisältää tagit" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "sääntötyyppi" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "arvo" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "suodatussääntö" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "suodatussäännöt" -#: documents/models.py:521 -msgid "started" -msgstr "aloitettu" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Virheellinen regex-lauseke: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Virheellinen väri." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Tiedostotyyppiä %(type)s ei tueta" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Virheellinen muuttuja havaittu." @@ -444,87 +556,87 @@ msgstr "Salasana" msgid "Sign in" msgstr "Kirjaudu sisään" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Englanti (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "valkovenäjä" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Tšekki" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Tanska" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Saksa" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Englanti (US)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Espanja" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Ranska" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italia" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxemburg" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Hollanti" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "puola" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "portugali (Brasilia)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "portugali" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "romania" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "venäjä" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slovenia" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Serbia" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "ruotsi" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turkki" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Kiina (yksinkertaistettu)" diff --git a/src/locale/fr_FR/LC_MESSAGES/django.po b/src/locale/fr_FR/LC_MESSAGES/django.po index 75b58e884..f04e63dba 100644 --- a/src/locale/fr_FR/LC_MESSAGES/django.po +++ b/src/locale/fr_FR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-09-07 21:41\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Documents" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Un des mots" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Tous les mots" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Concordance exacte" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Expression régulière" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Mot approximatif" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatique" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "nom" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "rapprochement" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algorithme de rapprochement" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "est insensible à la casse" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "correspondant" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "correspondants" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "couleur" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "est une étiquette de boîte de réception" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Marque cette étiquette comme étiquette de boîte de réception : ces étiquettes sont affectées à tous les documents nouvellement traités." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "étiquette" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "étiquettes" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "type de document" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "types de document" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "chemin" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "chemin de stockage" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "chemins de stockage" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Non chiffré" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Chiffré avec GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "titre" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "contenu" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Les données brutes du document, en format texte uniquement. Ce champ est principalement utilisé pour la recherche." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "type mime" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "somme de contrôle" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "La somme de contrôle du document original." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "somme de contrôle de l'archive" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "La somme de contrôle du document archivé." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "créé le" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "modifié" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "forme d'enregistrement :" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "date d'ajout" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "nom du fichier" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Nom du fichier courant en base de données" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "nom de fichier de l'archive" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Nom du fichier d'archive courant en base de données" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "numéro de série de l'archive" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Le classement de ce document dans votre archive de documents physiques." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "document" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "documents" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "débogage" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informations" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "avertissement" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "erreur" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "critique" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "groupe" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "message" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "niveau" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "journal" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "journaux" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "vue enregistrée" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "vues enregistrées" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "utilisateur" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "montrer sur le tableau de bord" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "montrer dans la barre latérale" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "champ de tri" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "tri inverse" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "le titre contient" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "le contenu contient" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "le NSA est" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "le correspondant est" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "le type de document est" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "est dans la boîte de réception" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "porte l'étiquette" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "porte l'une des étiquettes" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "créé avant" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "créé après" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "l'année de création est" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "le mois de création est" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "le jour de création est" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "ajouté avant" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "ajouté après" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "modifié avant" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "modifié après" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "ne porte pas d'étiquette" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "ne porte pas de NSA" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "le titre ou le contenu contient" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "recherche en texte intégral" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "documents relatifs" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "porte une étiquette parmi" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "type de règle" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "valeur" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "règle de filtrage" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "règles de filtrage" -#: documents/models.py:521 -msgid "started" -msgstr "démarré" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Expression régulière incorrecte : %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Couleur incorrecte." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Type de fichier %(type)s non pris en charge" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Variable non valide détectée." @@ -444,87 +556,87 @@ msgstr "Mot de passe" msgid "Sign in" msgstr "S'identifier" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Anglais (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Biélorusse" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Tchèque" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Danois" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Allemand" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Anglais (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Espagnol" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Français" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italien" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxembourgeois" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Néerlandais" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polonais" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugais (Brésil)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugais" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Roumain" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Russe" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slovène" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Serbe" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Suédois" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turc" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Chinois simplifié" diff --git a/src/locale/he_IL/LC_MESSAGES/django.po b/src/locale/he_IL/LC_MESSAGES/django.po index 4e72bc604..8f23c554f 100644 --- a/src/locale/he_IL/LC_MESSAGES/django.po +++ b/src/locale/he_IL/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-08 22:06\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Hebrew\n" "Language: he_IL\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "מסמכים" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "מילה כלשהי" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "כל המילים" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "התאמה מדוייקת" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "ביטוי רגולרי" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "מילה מעורפלת" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "אוטומטי" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "שם" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "התאמה" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "אלגוריתם התאמה" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "אינו רגיש" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "מכותב" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "מכותבים" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "צבע" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "תגית דואר נכנס" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "מסמן תגית זו כתגית דואר נכנס: כל המסמכים החדשים שהתקבלו יתויגו עם תגית דואר נכנס." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "תגית" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "תגיות" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "סוג מסמך" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "סוגי מסמך" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "נתיב" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "נתיב אכסון" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "נתיבי אכסון" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "לא מוצפן" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "הוצפן באמצעות GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "כותרת" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "תוכן" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "הנתונים הגולמיים של המסמך, המכילים טקסט בלבד. שדה זה משמש בעיקר לצורך חיפוש." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "סוג mime" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "מחרוזת בדיקה" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "מחרוזת בדיקה של המסמך המקורי." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "מחרוזת בדיקה לארכיון" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "מחרוזת הבדיקה למסמך בארכיון." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "נוצר" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "נערך לאחרונה" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "סוג אחסון" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "התווסף" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "שם קובץ" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "שם קובץ נוכחי באחסון" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "שם קובץ בארכיון" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "שם קובץ ארכיוני נוכחי באחסון" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "מספר סידורי בארכיון" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "מיקומו של מסמך זה בארכיון המסמכים הפיזי שלך." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "מסמך" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "מסמכים" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "ניפוי שגיאות" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "מידע" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "אזהרה" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "שגיאה" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "קריטי" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "קבוצה" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "הודעה" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "רמה" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "יומן רישום" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "יומני רישום" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "תצוגה שמורה" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "תצוגות שמורות" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "משתמש" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "הצג בדשבורד" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "הצג בסרגל צידי" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "שדה המיון" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "מיין הפוך" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "כותרת מכילה" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "תוכן מכיל" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "מס\"ד הוא" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "מכותב הוא" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "סוג מסמך הוא" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "בתיבה הנכנסת" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "ישנו תיוג" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "ישנו כל תיוג" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "נוצר לפני" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "נוצר לאחר" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "נוצר בשנת" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "נוצר בחודש" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "נוצר ביום" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "הוסף לפני" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "הוסף אחרי" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "נערך לפני" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "נערך אחרי" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "אינו כולל את התיוג" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "אינו בעל מס\"ד" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "כותרת או תוכן מכילים" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "שאילתת טקסט מלא" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "עוד כמו זה" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "מכיל תגים ב-" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "סוג כלל" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "ערך" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "חוק סינון" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "חוקי סינון" -#: documents/models.py:521 -msgid "started" +#: documents/models.py:536 +msgid "Task ID" msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "ביטוי רגולרי בלתי חוקי: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "צבע לא חוקי." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "סוג קובץ %(type)s לא נתמך" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "משתנה לא חוקי זוהה." @@ -444,87 +556,87 @@ msgstr "סיסמה" msgid "Sign in" msgstr "התחבר" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "אנגלית (ארה\"ב)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "בלרוסית" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "צ'כית" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "דנית" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "גרמנית" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "אנגלית (בריטניה)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "ספרדית" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "צרפתית" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "איטלקית" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "לוקסמבורגית" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "הולנדית" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "פולנית" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "פורטוגזית (ברזיל)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "פורטוגזית" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "רומנית" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "רוסית" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "סלובנית" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "סרבית" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "שוודית" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "טורקית" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "סינית מופשטת" diff --git a/src/locale/hr_HR/LC_MESSAGES/django.po b/src/locale/hr_HR/LC_MESSAGES/django.po index d5b34f4e9..8e484555b 100644 --- a/src/locale/hr_HR/LC_MESSAGES/django.po +++ b/src/locale/hr_HR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-09 12:27\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:12\n" "Last-Translator: \n" "Language-Team: Croatian\n" "Language: hr_HR\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumenti" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Bilo koja riječ" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Sve riječi" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Točno podudaranje" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Uobičajeni izraz" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Nejasna riječ" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatski" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "ime" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "podudarati" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algoritam podudaranja" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "ne razlikuje velika i mala slova" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "dopisnik" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "dopisnici" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "boja" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "oznaka ulazne pošte (inbox)" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Označava ovu oznaku kao oznaku ulazne pošte (inbox): Svi novopotrošeni dokumenti bit će označeni oznakama ulazne pošte (inbox)." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "oznaka" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "oznake" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "vrsta dokumenta" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "vrste dokumenta" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "putanja" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "putanja pohrane" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "putanje pohrane" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Nekriptirano" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Enkriptirano s GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "naslov" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "sadržaj" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Neobrađeni tekstualni podaci dokumenta. Ovo se polje koristi prvenstveno za pretraživanje." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "vrste mime" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "kontrolni zbroj" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Kontrolni zbroj originalnog dokumenta." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "arhivski kontrolni zbroj" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Kontrolni zbroj arhiviranog dokumenta." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "stvoreno" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "modificiran" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "vrsta pohrane" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "dodano" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "naziv datoteke" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Trenutni naziv pohranjene datoteke" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "naziv arhivirane datoteke" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Trenutni naziv arhivirane pohranjene datoteke" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "arhivirani serijski broj" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Položaj ovog dokumenta u vašoj fizičkoj arhivi dokumenata." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "dokumenti" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "otklanjanje pogrešaka" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informacije" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "upozorenje" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "greška" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritično" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "grupa" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "poruka" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "razina" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "zapisnik" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "zapisnici" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "spremljen prikaz" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "spremljeni prikazi" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "korisnik" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "prikaži na nadzornoj ploči" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "prikaži u bočnoj traci" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "sortiraj polje" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "obrnuto sortiranje" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "naslov sadrži" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "sadržaj sadrži" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN je" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "dopisnik je" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "vrsta dokumenta je" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "nalazi se u ulaznoj pošti" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "ima oznaku" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "ima bilo kakvu oznaku" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "stvoreni prije" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "stvoreno poslije" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "godina stvaranja je" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "mjesec stvaranja je" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "dan stvaranja je" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "dodano prije" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "dodano poslije" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "modificirano prije" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "modificirano poslije" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "ne posjeduje oznaku" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "ne posjeduje ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "naziv ili sadržaj sadrži" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "upit za cijeli tekst" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "više poput ovog" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "sadrži oznake" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "vrsta pravila" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "vrijednost" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "pravilo filtera" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "pravila filtera" -#: documents/models.py:521 -msgid "started" -msgstr "započeto" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Nevažeći regularni izraz: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Nevažeća boja." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Vrsta datoteke %(type)s nije podržana" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Otkrivena je nevaljana vrsta datoteke." @@ -444,87 +556,87 @@ msgstr "Lozinka" msgid "Sign in" msgstr "Prijava" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Engleski (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Bjeloruski" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Češki" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Danski" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Njemački" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Engleski (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Španjolski" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Francuski" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Talijanski" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luksemburški" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Nizozemski" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Poljski" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugalski (Brazil)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugalski" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumunjski" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Ruski" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slovenski" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Srpski" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Švedski" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turski" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Pojednostavljeni kineski" diff --git a/src/locale/it_IT/LC_MESSAGES/django.po b/src/locale/it_IT/LC_MESSAGES/django.po index c827d96f0..92c0790a5 100644 --- a/src/locale/it_IT/LC_MESSAGES/django.po +++ b/src/locale/it_IT/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-08-03 11:24\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-12 10:50\n" "Last-Translator: \n" "Language-Team: Italian\n" "Language: it_IT\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Documenti" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Qualsiasi parola" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Tutte le parole" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Corrispondenza esatta" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Espressione regolare" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Parole fuzzy" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatico" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "nome" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "corrispondenza" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algoritmo di corrispondenza" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "non distingue maiuscole e minuscole" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "corrispondente" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "corrispondenti" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "colore" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "è tag di arrivo" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Contrassegna questo tag come tag in arrivo: tutti i documenti elaborati verranno taggati con questo tag." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "tag" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "tag" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "tipo di documento" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "tipi di documento" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "percorso" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "percorso di archiviazione" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "percorsi di archiviazione" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Non criptato" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Criptato con GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "titolo" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "contenuto" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "I dati grezzi o solo testo del documento. Questo campo è usato principalmente per la ricerca." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "tipo mime" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "checksum" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Il checksum del documento originale." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "checksum dell'archivio" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Il checksum del documento archiviato." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "creato il" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "modificato il" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "tipo di storage" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "aggiunto il" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "nome del file" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Nome del file corrente nello storage" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "Nome file in archivio" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Il nome del file nell'archiviazione" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "nome file originale" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "Il nome originale del file quando è stato caricato" + +#: documents/models.py:231 msgid "archive serial number" msgstr "numero seriale dell'archivio" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Posizione di questo documento all'interno dell'archivio fisico." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "documento" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "documenti" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "debug" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informazione" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "avvertimento" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "errore" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "critico" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "gruppo" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "messaggio" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "livello" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "logs" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "log" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "vista salvata" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "viste salvate" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "utente" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "mostra sul cruscotto" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "mostra nella barra laterale" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "campo di ordinamento" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "ordine invertito" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "il titolo contiene" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "il contenuto contiene" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN è" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "la corrispondenza è" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "il tipo di documento è" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "è in arrivo" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "ha etichetta" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "ha qualsiasi etichetta" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "creato prima del" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "creato dopo il" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "l'anno di creazione è" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "il mese di creazione è" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "il giorno di creazione è" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "aggiunto prima del" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "aggiunto dopo il" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "modificato prima del" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "modificato dopo" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "non ha tag" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "non ha ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "il titolo o il contenuto contiene" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "query fulltext" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "altro come questo" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "ha tag in" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "ASN maggiore di" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "ASN minore di" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "il percorso di archiviazione è" + +#: documents/models.py:422 msgid "rule type" msgstr "tipo di regola" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "valore" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "regola filtro" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "regole filtro" -#: documents/models.py:521 -msgid "started" -msgstr "avviato" +#: documents/models.py:536 +msgid "Task ID" +msgstr "ID Attività" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "commento" + +#: documents/models.py:643 +msgid "comments" +msgstr "commenti" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Espressione regolare non valida: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Colore non valido." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Il tipo di file %(type)s non è supportato" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Variabile non valida." @@ -444,87 +556,87 @@ msgstr "Password" msgid "Sign in" msgstr "Accedi" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Inglese (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Bielorusso" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Ceco" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Danese" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Tedesco" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Inglese (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Spagnolo" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Francese" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italiano" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Lussemburghese" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Olandese" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polacco" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portoghese (Brasile)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portoghese" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumeno" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Russo" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Sloveno" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Serbo" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Svedese" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turco" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Cinese semplificato" diff --git a/src/locale/lb_LU/LC_MESSAGES/django.po b/src/locale/lb_LU/LC_MESSAGES/django.po index d9d85b767..e7c1b2234 100644 --- a/src/locale/lb_LU/LC_MESSAGES/django.po +++ b/src/locale/lb_LU/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-08 22:07\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:12\n" "Last-Translator: \n" "Language-Team: Luxembourgish\n" "Language: lb_LU\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumenter" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Iergendee Wuert" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "All d'Wierder" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Exakten Treffer" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Regulären Ausdrock" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Ongenaut Wuert" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatesch" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "Numm" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "Zouweisungsmuster" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "Zouweisungsalgorithmus" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "Grouss-/Klengschreiwung ignoréieren" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "Korrespondent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "Korrespondenten" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "Faarf" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "Postaganks-Etikett" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Dës Etikett als Postaganks-Etikett markéieren: All nei importéiert Dokumenter kréien ëmmer dës Etikett zougewisen." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "Etikett" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "Etiketten" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "Dokumententyp" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "Dokumententypen" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "Pfad" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "Späicherpfad" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "Späicherpfaden" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Onverschlësselt" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Verschlësselt mat GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "Titel" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "Inhalt" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "De réien Textinhalt vum Dokument. Dëst Feld gëtt primär fir d'Sich benotzt." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "MIME-Typ" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "Préifzomm" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "D'Préifzomm vum Original-Dokument." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "Archiv-Préifzomm" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "D'Préifzomm vum archivéierten Dokument." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "erstallt" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "verännert" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "Späichertyp" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "derbäigesat" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "Fichiersnumm" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Aktuellen Dateinumm am Späicher" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "Archiv-Dateinumm" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Aktuellen Dateinumm am Archiv" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "Archiv-Seriennummer" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "D'Positioun vun dësem Dokument am physeschen Dokumentenarchiv." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "Dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "Dokumenter" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "Fehlersiich" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "Informatioun" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "Warnung" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "Feeler" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritesch" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "Grupp" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "Message" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "Niveau" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "Protokoll" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "Protokoller" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "Gespäichert Usiicht" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "Gespäichert Usiichten" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "Benotzer" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "Op der Startsäit uweisen" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "An der Säiteleescht uweisen" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "Zortéierfeld" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "ëmgedréint zortéieren" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "Titel enthält" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "Inhalt enthält" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN ass" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "Korrespondent ass" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "Dokumententyp ass" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "ass am Postagank" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "huet Etikett" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "huet iergendeng Etikett" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "erstallt virun" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "erstallt no" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "Erstellungsjoer ass" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "Erstellungsmount ass" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "Erstellungsdag ass" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "dobäigesat virun" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "dobäigesat no" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "verännert virun" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "verännert no" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "huet dës Etikett net" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "huet keng ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "Titel oder Inhalt enthalen" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "Volltextsich" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "ähnlech Dokumenter" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "huet Etiketten an" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "Reegeltyp" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "Wäert" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "Filterreegel" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "Filterreegelen" -#: documents/models.py:521 -msgid "started" +#: documents/models.py:536 +msgid "Task ID" msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Ongëltege regulären Ausdrock: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Ongëlteg Faarf." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Fichierstyp %(type)s net ënnerstëtzt" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Ongëlteg Zeechen detektéiert." @@ -444,87 +556,87 @@ msgstr "Passwuert" msgid "Sign in" msgstr "Umellen" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Englesch (USA)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Belarusesch" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Tschechesch" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Dänesch" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Däitsch" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Englesch (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Spuenesch" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Franséisch" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italienesch" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Lëtzebuergesch" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Hollännesch" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polnesch" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugisesch (Brasilien)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugisesch" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumänesch" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Russesch" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slowenesch" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Serbesch" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Schwedesch" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Tierkesch" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Chinesesch (Vereinfacht)" diff --git a/src/locale/nl_NL/LC_MESSAGES/django.po b/src/locale/nl_NL/LC_MESSAGES/django.po index db1047e5b..4cf2fb4a5 100644 --- a/src/locale/nl_NL/LC_MESSAGES/django.po +++ b/src/locale/nl_NL/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-10-27 09:51\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:12\n" "Last-Translator: \n" "Language-Team: Dutch\n" "Language: nl_NL\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Documenten" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Elk woord" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Alle woorden" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Exacte overeenkomst" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Reguliere expressie" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Gelijkaardig woord" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatisch" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "naam" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "Overeenkomst" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "Algoritme voor het bepalen van de overeenkomst" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "is niet hoofdlettergevoelig" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "correspondent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "correspondenten" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "Kleur" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "is \"Postvak in\"-label" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Markeert dit label als een \"Postvak in\"-label: alle nieuw verwerkte documenten krijgen de \"Postvak in\"-labels." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "label" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "labels" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "documenttype" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "documenttypen" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "pad" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "opslag pad" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "opslag paden" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Niet versleuteld" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Versleuteld met GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "titel" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "inhoud" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "De onbewerkte gegevens van het document. Dit veld wordt voornamelijk gebruikt om te zoeken." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "mimetype" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "checksum" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "De checksum van het oorspronkelijke document." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "archief checksum" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "De checksum van het gearchiveerde document." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "aangemaakt" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "gewijzigd" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "type opslag" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "toegevoegd" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "bestandsnaam" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Huidige bestandsnaam in opslag" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "Bestandsnaam in archief" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Huidige bestandsnaam in archief" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "serienummer in archief" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "De positie van dit document in je fysieke documentenarchief." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "document" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "documenten" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "debug" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informatie" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "waarschuwing" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "fout" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritisch" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "groep" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "bericht" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "niveau" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "bericht" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "berichten" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "opgeslagen view" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "opgeslagen views" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "gebruiker" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "weergeven op dashboard" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "weergeven in zijbalk" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "sorteerveld" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "omgekeerd sorteren" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "titel bevat" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "inhoud bevat" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN is" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "correspondent is" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "documenttype is" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "zit in \"Postvak in\"" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "heeft label" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "heeft één van de labels" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "aangemaakt voor" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "aangemaakt na" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "aangemaakt jaar is" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "aangemaakte maand is" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "aangemaakte dag is" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "toegevoegd voor" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "toegevoegd na" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "gewijzigd voor" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "gewijzigd na" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "heeft geen label" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "heeft geen ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "titel of inhoud bevat" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "inhoud doorzoeken" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "meer zoals dit" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "heeft tags in" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "type regel" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "waarde" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "filterregel" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "filterregels" -#: documents/models.py:521 -msgid "started" -msgstr "gestart" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Ongeldige reguliere expressie: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Ongeldig kleur." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Bestandstype %(type)s niet ondersteund" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Ongeldige variabele ontdekt." @@ -444,87 +556,87 @@ msgstr "Wachtwoord" msgid "Sign in" msgstr "Aanmelden" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Engels (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Wit-Russisch" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Tsjechisch" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Deens" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Duits" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Engels (Brits)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Spaans" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Frans" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italiaans" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxemburgs" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Nederlands" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Pools" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugees (Brazilië)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugees" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Roemeens" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Russisch" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Sloveens" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Servisch" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Zweeds" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turks" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Chinees (vereenvoudigd)" diff --git a/src/locale/no_NO/LC_MESSAGES/django.po b/src/locale/no_NO/LC_MESSAGES/django.po index d5a1a2b09..edd2901c2 100644 --- a/src/locale/no_NO/LC_MESSAGES/django.po +++ b/src/locale/no_NO/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-08-03 08:59\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-29 08:29\n" "Last-Translator: \n" "Language-Team: Norwegian\n" "Language: no_NO\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumenter" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Hvilket som helst ord" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Alle ord" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Eksakt match" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Regulære uttrykk" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Fuzzy word" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatisk" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "navn" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "treff" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "samsvarende algoritme" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "er insensitiv" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "korrespondent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "korrespondenter" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "farge" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "er innboks tag" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Markerer dette merket som en innboks-tag: Alle nybrukte dokumenter vil bli merket med innboks-tagger." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "tagg" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "tagger" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "dokument type" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "dokumenttyper" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "sti" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "lagringssti" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "lagringsveier" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Ukryptert" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Kryptert med GNU Personvernvakt" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "tittel" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "innhold" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Raw, tekstbare data fra dokumentet. Dette feltet brukes primært for søking." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "mime type" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "sjekksum" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Sjekksummen av det opprinnelige dokumentet." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "arkiv sjekksum" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Sjekksummen av det arkiverte dokumentet." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "opprettet" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "endret" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "lagringstype" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "lagt til" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "filnavn" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Gjeldende filnavn i lagring" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "arkiver filnavn" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Gjeldende arkiv filnavn i lagring" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "opprinnelig filnavn" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "Det opprinnelige filnavnet da den ble lastet opp" + +#: documents/models.py:231 msgid "archive serial number" msgstr "arkiver serienummer" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Dokumentets posisjon i ditt fysiske dokumentarkiv." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "dokumenter" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "feilsøk" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informasjon" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "advarsel" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "feil" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritisk" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "gruppe" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "melding" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "nivå" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "Logg" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "logger" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "lagret visning" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "lagrede visninger" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "bruker" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "vis på dashbordet" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "vis i sidestolpen" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "sorter felt" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "sorter på baksiden" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "tittelen inneholder" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "innholdet inneholder" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN er" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "tilsvarendet er" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "dokumenttype er" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "er i innboksen" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "har tagg" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "har en tag" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "opprettet før" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "opprettet etter" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "opprettet år er" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "opprettet måned er" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "opprettet dag er" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "lagt til før" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "lagt til etter" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "endret før" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "endret etter" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "har ikke tagg" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "har ikke ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "tittel eller innhold inneholder" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "full tekst spørring" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "mer som dette" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "har tags i" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "ASN større enn" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "ASN mindre enn" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "lagringssti er" + +#: documents/models.py:422 msgid "rule type" msgstr "Type regel" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "verdi" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "filtrer regel" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "filtrer regler" -#: documents/models.py:521 -msgid "started" -msgstr "startet" +#: documents/models.py:536 +msgid "Task ID" +msgstr "Oppgave ID" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "Celery ID for oppgaven som ble kjørt" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "Bekreftet" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "Hvis oppgaven bekreftes via frontend eller API" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "Oppgavenavn" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "Navn på filen som oppgaven ble kjørt for" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "Navn på Oppgaven som ble kjørt" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Ugyldig regulært uttrykk: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Ugyldig farge." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Filtype %(type)s støttes ikke" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Ugyldig variabel oppdaget." @@ -444,87 +556,87 @@ msgstr "Passord" msgid "Sign in" msgstr "Logg inn" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Engelsk (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Hviterussisk" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Tsjekkisk" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Dansk" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Tysk" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Engelsk (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Spansk" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Fransk" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italiensk" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxembourgsk" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Nederlandsk" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polsk" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugisisk (Brasil)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugisisk" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumensk" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Russisk" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slovenian" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Serbisk" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Svensk" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Tyrkisk" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Kinesisk forenklet" diff --git a/src/locale/pl_PL/LC_MESSAGES/django.po b/src/locale/pl_PL/LC_MESSAGES/django.po index 29ca75596..4167a48ec 100644 --- a/src/locale/pl_PL/LC_MESSAGES/django.po +++ b/src/locale/pl_PL/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-08-17 11:20\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-28 16:30\n" "Last-Translator: \n" "Language-Team: Polish\n" "Language: pl_PL\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumenty" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Dowolne słowo" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Wszystkie słowa" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Dokładne dopasowanie" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Wyrażenie regularne" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Dopasowanie rozmyte" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatyczny" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "nazwa" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "dopasowanie" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algorytm dopasowania" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "bez rozróżniania wielkości znaków" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "korespondent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "korespondenci" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "kolor" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "jest tagiem skrzynki odbiorczej" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Zaznacza ten tag jako tag skrzynki odbiorczej: Wszystkie nowo przetworzone dokumenty będą oznaczone tagami skrzynki odbiorczej." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "znacznik" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "tagi" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "typ dokumentu" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "typy dokumentów" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "ścieżka" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "ścieżka przechowywania" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "ścieżki składowania" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Niezaszyfrowane" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Zaszyfrowane przy użyciu GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "tytuł" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "zawartość" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Surowe, tekstowe dane dokumentu. To pole jest używane głównie do wyszukiwania." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "mime type" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "suma kontrolna" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Suma kontrolna oryginalnego dokumentu." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "suma kontrolna archiwum" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Suma kontrolna zarchiwizowanego dokumentu." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "utworzono" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "zmodyfikowano" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "typ przechowywania" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "dodano" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "nazwa pliku" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Aktualna nazwa pliku w pamięci" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "nazwa pliku archiwum" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Aktualna nazwa pliku archiwum w pamięci" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "oryginalna nazwa pliku" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "Oryginalna nazwa pliku, gdy został przesłany" + +#: documents/models.py:231 msgid "archive serial number" msgstr "numer seryjny archiwum" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Pozycja tego dokumentu w archiwum dokumentów fizycznych." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "dokumenty" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "debugowanie" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informacja" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "ostrzeżenie" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "błąd" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "krytyczne" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "grupa" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "wiadomość" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "poziom" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "log" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "logi" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "zapisany widok" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "zapisane widoki" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "użytkownik" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "pokaż na stronie głównej" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "pokaż na pasku bocznym" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "pole sortowania" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "sortuj malejąco" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "tytuł zawiera" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "zawartość zawiera" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "numer archiwum jest" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "korespondentem jest" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "typ dokumentu jest" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "jest w skrzynce odbiorczej" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "ma tag" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "ma dowolny tag" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "utworzony przed" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "utworzony po" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "rok utworzenia to" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "miesiąc utworzenia to" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "dzień utworzenia to" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "dodany przed" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "dodany po" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "zmodyfikowany przed" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "zmodyfikowany po" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "nie ma tagu" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "nie ma numeru archiwum" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "tytuł lub zawartość zawiera" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "zapytanie pełnotekstowe" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "podobne dokumenty" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "ma znaczniki w" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "ASN większy niż" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "ASN mniejszy niż" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "ścieżką przechowywania jest" + +#: documents/models.py:422 msgid "rule type" msgstr "typ reguły" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "wartość" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "reguła filtrowania" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "reguły filtrowania" -#: documents/models.py:521 -msgid "started" -msgstr "start" +#: documents/models.py:536 +msgid "Task ID" +msgstr "ID zadania" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "ID Celery dla zadania, które zostało uruchomione" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "Potwierdzono" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "Jeśli zadanie jest potwierdzone przez frontend lub API" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "Nazwa zadania" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "Stan zadania" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "Dane zwrócone przez zadanie" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "Komentarz do dokumentu" + +#: documents/models.py:642 +msgid "comment" +msgstr "komentarz" + +#: documents/models.py:643 +msgid "comments" +msgstr "komentarze" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Nieprawidłowe wyrażenie regularne: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Nieprawidłowy kolor." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Typ pliku %(type)s nie jest obsługiwany" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Wykryto nieprawidłową zmienną." @@ -444,87 +556,87 @@ msgstr "Hasło" msgid "Sign in" msgstr "Zaloguj się" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Angielski (USA)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Białoruski" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Czeski" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Duński" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Niemiecki" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Angielski (Wielka Brytania)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Hiszpański" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Francuski" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Włoski" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luksemburski" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Holenderski" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polski" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugalski (Brazylia)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugalski" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumuński" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Rosyjski" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Słoweński" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Serbski" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Szwedzki" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turecki" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Chiński uproszczony" diff --git a/src/locale/pt_BR/LC_MESSAGES/django.po b/src/locale/pt_BR/LC_MESSAGES/django.po index 4690bd84d..1be9d6460 100644 --- a/src/locale/pt_BR/LC_MESSAGES/django.po +++ b/src/locale/pt_BR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-08 22:07\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Portuguese, Brazilian\n" "Language: pt_BR\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Documentos" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Qualquer palavra" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Todas as palavras" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Detecção exata" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Expressão regular" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Palavra difusa (fuzzy)" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automático" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "nome" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "detecção" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algoritmo de detecção" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "diferencia maiúsculas de minúsculas" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "correspondente" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "correspondentes" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "cor" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "é etiqueta caixa de entrada" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Marca essa etiqueta como caixa de entrada: Todos os novos documentos consumidos terão as etiquetas de caixa de entrada." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "etiqueta" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "etiquetas" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "tipo de documento" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "tipos de documento" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Não encriptado" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Encriptado com GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "título" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "conteúdo" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "O conteúdo de texto bruto do documento. Esse campo é usado principalmente para busca." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "tipo mime" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "some de verificação" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "A soma de verificação original do documento." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "Soma de verificação de arquivamento." -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "A soma de verificação do documento arquivado." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "criado" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "modificado" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "tipo de armazenamento" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "adicionado" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "nome do arquivo" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Nome do arquivo atual armazenado" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "nome do arquivo para arquivamento" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Nome do arquivo para arquivamento armazenado" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "número de sério de arquivamento" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "A posição deste documento no seu arquivamento físico." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "documento" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "documentos" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "debug" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informação" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "aviso" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "erro" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "crítico" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "grupo" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "mensagem" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "nível" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "log" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "logs" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "visualização" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "visualizações" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "usuário" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "exibir no painel de controle" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "exibir no painel lateral" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "ordenar campo" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "odernar reverso" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "título contém" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "conteúdo contém" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "NSA é" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "correspondente é" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "tipo de documento é" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "é caixa de entrada" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "contém etiqueta" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "contém qualquer etiqueta" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "criado antes de" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "criado depois de" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "ano de criação é" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "mês de criação é" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "dia de criação é" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "adicionado antes de" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "adicionado depois de" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "modificado antes de" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "modificado depois de" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "não tem etiqueta" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "não tem NSA" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "título ou conteúdo contém" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "pesquisa de texto completo" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "mais como este" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "contém etiqueta em" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "tipo de regra" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "valor" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "regra de filtragem" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "regras de filtragem" -#: documents/models.py:521 -msgid "started" +#: documents/models.py:536 +msgid "Task ID" msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Expressão regular inválida: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Cor inválida." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Tipo de arquivo %(type)s não suportado" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "" @@ -444,87 +556,87 @@ msgstr "Senha" msgid "Sign in" msgstr "Entrar" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Inglês (EUA)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Tcheco" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Dinamarquês" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Alemão" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Inglês (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Espanhol" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Francês" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italiano" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxemburguês" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Holandês" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polonês" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Português (Brasil)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Português" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Romeno" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Russo" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Sueco" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "" diff --git a/src/locale/pt_PT/LC_MESSAGES/django.po b/src/locale/pt_PT/LC_MESSAGES/django.po index f805a7e6b..4f3b0e9e3 100644 --- a/src/locale/pt_PT/LC_MESSAGES/django.po +++ b/src/locale/pt_PT/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-08 22:07\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Portuguese\n" "Language: pt_PT\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Documentos" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Qualquer palavra" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Todas as palavras" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Detecção exata" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Expressão regular" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Palavra difusa (fuzzy)" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automático" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "nome" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "correspondência" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algoritmo correspondente" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "é insensível" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "correspondente" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "correspondentes" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "cor" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "é etiqueta de novo" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Marca esta etiqueta como uma etiqueta de entrada. Todos os documentos recentemente consumidos serão etiquetados com a etiqueta de entrada." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "etiqueta" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "etiquetas" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "tipo de documento" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "tipos de documento" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Não encriptado" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Encriptado com GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "título" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "conteúdo" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Os dados de texto, em cru, do documento. Este campo é utilizado principalmente para pesquisar." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "tipo mime" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "soma de verificação" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "A soma de verificação do documento original." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "arquivar soma de verificação" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "A soma de verificação do documento arquivado." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "criado" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "modificado" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "tipo de armazenamento" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "adicionado" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "nome de ficheiro" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Nome do arquivo atual no armazenamento" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "nome do ficheiro de arquivo" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Nome do arquivo atual em no armazenamento" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "numero de série de arquivo" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "A posição do documento no seu arquivo físico de documentos." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "documento" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "documentos" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "depurar" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informação" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "aviso" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "erro" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "crítico" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "grupo" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "mensagem" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "nível" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "registo" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "registos" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "vista guardada" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "vistas guardadas" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "utilizador" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "exibir no painel de controlo" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "mostrar na navegação lateral" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "ordenar campo" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "ordenar inversamente" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "o título contém" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "o conteúdo contém" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "O NSA é" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "o correspondente é" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "o tipo de documento é" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "está na entrada" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "tem etiqueta" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "tem qualquer etiqueta" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "criado antes" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "criado depois" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "ano criada é" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "mês criado é" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "dia criado é" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "adicionada antes" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "adicionado depois de" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "modificado antes de" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "modificado depois de" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "não tem etiqueta" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "não possui um NSA" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "título ou conteúdo contém" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "consulta de texto completo" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "mais como este" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "tem etiquetas em" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "tipo de regra" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "valor" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "regra de filtragem" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "regras de filtragem" -#: documents/models.py:521 -msgid "started" +#: documents/models.py:536 +msgid "Task ID" msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Expressão regular inválida: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Cor invalida." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Tipo de arquivo %(type)s não suportado" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "" @@ -444,87 +556,87 @@ msgstr "Palavra-passe" msgid "Sign in" msgstr "Iniciar sessão" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Inglês (EUA)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Checo" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Dinamarquês" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Deutsch" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Inglês (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Espanhol" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Français" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italiano" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxemburguês" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Nederlandse" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polaco" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Português (Brasil)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Português" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Romeno" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Russo" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Sueco" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "" diff --git a/src/locale/ro_RO/LC_MESSAGES/django.po b/src/locale/ro_RO/LC_MESSAGES/django.po index c1297a8b3..017ac9144 100644 --- a/src/locale/ro_RO/LC_MESSAGES/django.po +++ b/src/locale/ro_RO/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-08 22:07\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:12\n" "Last-Translator: \n" "Language-Team: Romanian\n" "Language: ro_RO\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Documente" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Orice cuvânt" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Toate cuvintele" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Potrivire exactă" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Expresie regulată" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Mod neatent" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automat" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "nume" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "potrivire" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algoritm de potrivire" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "nu ține cont de majuscule" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "corespondent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "corespondenți" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "culoare" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "este etichetă inbox" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Marchează aceasta eticheta ca etichetă inbox: Toate documentele nou consumate primesc aceasta eticheta." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "etichetă" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "etichete" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "tip de document" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "tipuri de document" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Necriptat" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Criptat cu GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "titlu" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "conținut" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Textul brut al documentului. Acest camp este folosit in principal pentru căutare." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "tip MIME" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "sumă de control" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Suma de control a documentului original." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "suma de control a arhivei" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Suma de control a documentului arhivat." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "creat" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "modificat" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "tip de stocare" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "adăugat" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "nume fișier" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Numele curent al fișierului stocat" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "nume fișier arhiva" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Numele curent al arhivei stocate" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "număr serial in arhiva" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Poziția acestui document in arhiva fizica." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "document" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "documente" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "depanare" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informații" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "avertizare" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "eroare" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "critic" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "grup" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "mesaj" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "nivel" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "jurnal" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "jurnale" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "vizualizare" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "vizualizări" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "utilizator" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "afișează pe tabloul de bord" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "afișează in bara laterala" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "sortează camp" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "sortează invers" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "titlul conține" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "conținutul conține" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "Avizul prealabil de expediție este" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "corespondentul este" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "tipul documentului este" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "este în inbox" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "are eticheta" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "are orice eticheta" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "creat înainte de" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "creat după" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "anul creării este" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "luna creării este" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "ziua creării este" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "adăugat înainte de" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "adăugat după" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "modificat înainte de" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "modificat după" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "nu are etichetă" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "nu are aviz prealabil de expediție" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "titlul sau conținutul conține" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "query fulltext" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "mai multe ca aceasta" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "are etichete în" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "tip de regula" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "valoare" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "regulă de filtrare" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "reguli de filtrare" -#: documents/models.py:521 -msgid "started" +#: documents/models.py:536 +msgid "Task ID" msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Expresie regulată invalida: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Culoare invalidă." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Tip de fișier %(type)s nesuportat" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "" @@ -444,87 +556,87 @@ msgstr "Parolă" msgid "Sign in" msgstr "Conectare" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Engleză (Americană)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Cehă" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Daneză" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Germană" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Engleză (Britanică)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Spaniolă" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Franceză" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italiană" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luxemburgheză" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Olandeză" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Poloneză" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugheză (Brazilia)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugheză" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Română" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Rusă" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Suedeză" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "" diff --git a/src/locale/ru_RU/LC_MESSAGES/django.po b/src/locale/ru_RU/LC_MESSAGES/django.po index d5b200971..3134f1169 100644 --- a/src/locale/ru_RU/LC_MESSAGES/django.po +++ b/src/locale/ru_RU/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-08-03 16:12\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Russian\n" "Language: ru_RU\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Документы" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Любые слова" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Все слова" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Точное соответствие" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Регулярное выражение" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "\"Нечёткий\" режим" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Автоматически" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "имя" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "соответствие" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "алгоритм сопоставления" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "без учёта регистра" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "корреспондент" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "корреспонденты" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "цвет" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "это входящий тег" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Отметить этот тег как «Входящий»: все вновь добавленные документы будут помечены тегами «Входящие»." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "тег" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "теги" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "тип документа" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "типы документов" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "путь" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "путь к хранилищу" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "пути хранения" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "не зашифровано" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Зашифровано с помощью GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "заголовок" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "содержимое" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Это поле используется в основном для поиска." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "тип Mime" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "контрольная сумма" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Контрольная сумма оригинального документа." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "контрольная сумма архива" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Контрольная сумма архивного документа." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "создано" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "изменено" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "тип хранилища" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "добавлено" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "имя файла" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Текущее имя файла в хранилище" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "имя файла архива" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Текущее имя файла архива в хранилище" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "архивный номер (АН)" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Позиция этого документа в вашем физическом архиве документов." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "документ" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "документы" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "отладка" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "информация" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "предупреждение" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "ошибка" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "критическая" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "группа" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "сообщение" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "уровень" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "журнал" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "логи" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "сохранённое представление" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "сохраненные представления" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "пользователь" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "показать на панели" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "показать в боковой панели" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "Поле сортировки" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "обратная сортировка" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "заголовок содержит" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "содержимое содержит" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "АН" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "корреспондент" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "тип документа" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "во входящих" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "есть тег" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "есть любой тег" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "создан до" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "создан после" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "год создания" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "месяц создания" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "день создания" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "добавлен до" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "добавлен после" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "изменен до" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "изменен после" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "не имеет тега" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "не имеет архивного номера" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "Название или содержимое включает" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "полнотекстовый запрос" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "больше похожих" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "имеет теги в" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "Тип правила" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "значение" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "Правило фильтрации" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "правила фильтрации" -#: documents/models.py:521 -msgid "started" -msgstr "запущено" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "неверное регулярное выражение: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Неверный цвет." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Тип файла %(type)s не поддерживается" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Обнаружена неверная переменная." @@ -444,87 +556,87 @@ msgstr "Пароль" msgid "Sign in" msgstr "Вход" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Английский (США)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Белорусский" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Чешский" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Датский" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Немецкий" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Английский (Великобритании)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Испанский" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Французский" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Итальянский" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Люксембургский" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Датский" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Польский" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Португальский (Бразилия)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Португальский" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Румынский" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Русский" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Словенский" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Сербский" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Шведский" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Турецкий" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Китайский упрощенный" diff --git a/src/locale/sl_SI/LC_MESSAGES/django.po b/src/locale/sl_SI/LC_MESSAGES/django.po index f1e408407..2320afcd0 100644 --- a/src/locale/sl_SI/LC_MESSAGES/django.po +++ b/src/locale/sl_SI/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-08-25 12:46\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Slovenian\n" "Language: sl_SI\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumenti" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Katerakoli beseda" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Vse besede" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Točno ujemanje" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Regularni izraz" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Fuzzy beseda" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Samodejno" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "ime" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "ujemanje" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algoritem ujemanja" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "brez razlikovanje velikosti črk" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "dopisnik" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "dopisniki" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "barva" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "je vhodna oznaka" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Označi to oznako kot vhodno oznako: vsi na novo obdelani dokumenti bodo označeni z vhodno oznako." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "oznaka" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "oznake" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "vrsta dokumenta" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "vrste dokumentov" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "pot" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "pot do shrambe" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "poti do shrambe" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Nešifrirano" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Šifrirano z GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "naslov" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "vsebina" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Neobdelani besedilni podatki dokumenta. To polje se uporablja predvsem za iskanje." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "vrsta mime" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "kontrolna vsota" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Kontrolna vsota izvirnega dokumenta." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "arhivska kontrolna vsota" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Kontrolna vsota arhiviranega dokumenta." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "ustvarjeno" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "spremenjeno" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "vrsta shrambe" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "dodano" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "ime datoteke" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Trenutno ime dokumenta v shrambi" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "ime arhivske datoteke" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Trenutno ime arhivske datoteke v shrambi" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "arhivska serijska številka" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Položaj tega dokumenta v vašem fizičnem arhivu dokumentov." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "dokumenti" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "razhroščevanje" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informacija" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "opozorilo" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "napaka" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritično" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "skupina" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "sporočilo" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "nivo" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "dnevnik" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "dnevniki" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "shranjeni pogled" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "shranjeni pogledi" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "uporabnik" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "prikaži na pregledni plošči" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "prikaži v stranski vrstici" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "polje za razvrščanje" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "razvrsti obratno" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "naslov vsebuje" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "vsebina vsebuje" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN je" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "dopisnik je" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "vrsta dokumenta je" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "je v prejetem" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "ima oznako" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "ima katero koli oznako" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "ustvarjeno pred" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "ustvarjeno po" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "leto nastanka" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "mesec nastanka" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "dan nastanka" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "dodano pred" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "dodano po" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "spremenjeno pred" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "spremenjeno po" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "nima oznake" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "nima ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "naslov ali vsebina vsebujeta" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "polnobesedilna poizvedba" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "več takih" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "ima oznake" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "vrsta pravila" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "vrednost" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "filtriraj pravilo" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "filtriraj pravila" -#: documents/models.py:521 -msgid "started" -msgstr "zagnano" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Neveljaven splošen izraz: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Napačna barva." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Vrsta datoteke %(type)s ni podprta" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Zaznani neveljavni znaki." @@ -444,87 +556,87 @@ msgstr "Geslo" msgid "Sign in" msgstr "Prijava" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Angleščina (ZDA)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Beloruščina" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Češčina" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Danščina" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Nemščina" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Angleščina (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Španščina" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Francoščina" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italijanščina" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luksemburški" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Nizozemščina" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Poljščina" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugalščina (Brazilija)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugalščina" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Romunščina" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Ruščina" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slovenščina" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Srbščina" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Švedščina" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turščina" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Poenostavljena kitajščina" diff --git a/src/locale/sr_CS/LC_MESSAGES/django.po b/src/locale/sr_CS/LC_MESSAGES/django.po index ca01c8d1e..c7c5415de 100644 --- a/src/locale/sr_CS/LC_MESSAGES/django.po +++ b/src/locale/sr_CS/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-08-04 23:55\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-12 13:08\n" "Last-Translator: \n" "Language-Team: Serbian (Latin)\n" "Language: sr_CS\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokumenta" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Bilo koja reč" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Sve reči" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Tačno podudaranje" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Regularni izraz" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Fuzzy reč" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatski" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "naziv" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "poklapanje" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "algoritam podudaranja" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "bez razlike veliko/malo slovo" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "korespodent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "korespodenti" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "boja" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "je oznaka prijemnog sandučeta" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Označava ovu oznaku kao oznaku prijemnog sandučeta (inbox): Svi novoobrađeni dokumenti će biti označeni oznakama prijemnog sandučeta (inbox)." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "oznaka" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "oznake" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "tip dokumenta" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "tipovi dokumenta" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "putanja" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "putanja skladišta" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "putanja skladišta" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Nešifrovano" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Šifrovano pomoću GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "naslov" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "sadržaj" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Neobrađeni tekstualni podaci dokumenta. Ovo se polje koristi prvenstveno za pretraživanje." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "mime tip" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "kontrolna suma" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Kontrolna suma originalnog dokumenta." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "arhivni checksum" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Kontrolna suma arhivnog dokumenta." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "kreirano" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "izmenjeno" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "tip skladišta" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "dodato" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "naziv fajla" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Trenutni naziv sačuvane datoteke" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "naziv fajla arhive" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Trenutni naziv arhivirane sačuvane datoteke" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "originalno ime fajla" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "Originalni naziv fajla kada je otpremljen" + +#: documents/models.py:231 msgid "archive serial number" msgstr "arhivski serijski broj" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Položaj ovog dokumenta u vašoj fizičkoj arhivi dokumenata." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "dokumenta" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "okloni greške" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "informacija" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "upozorenje" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "grеška" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritično" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "grupa" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "poruka" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "nivo" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "log" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "logovi" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "sačuvani prikaz" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "sačuvani prikazi" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "korisnik" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "prikaži na kontrolnoj tabli" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "prikaži u bočnoj traci" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "polje za sortiranje" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "obrnuto sortiranje" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "naslov sadrži" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "sadržaj sadrži" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN je" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "korespodent je" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "tip dokumenta je" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "je u prijemnog sandučetu" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "ima oznaku" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "ima bilo koju oznaku" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "kreiran pre" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "kreiran posle" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "godina kreiranja je" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "mesec kreiranja je" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "dan kreiranja je" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "dodat pre" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "dodat posle" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "izmenjen pre" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "izmenjen posle" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "nema oznaku" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "nema ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "naslov i sadržaj sadrži" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "upit za ceo tekst" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "više ovakvih" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "ima oznake u" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "ASN veći od" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "ASN manji od" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "putanja skladišta je" + +#: documents/models.py:422 msgid "rule type" msgstr "tip pravila" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "vrednost" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "filter pravilo" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "filter pravila" -#: documents/models.py:521 -msgid "started" -msgstr "pokrenuto" +#: documents/models.py:536 +msgid "Task ID" +msgstr "ID Zadatka" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "Celery ID za zadatak koji je pokrenut" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "Potvrđeno" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "Ako je zadatak potvrđen preko frontenda ili API-ja" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "Ime zadatka" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "Naziv fajla za koji je zadatak pokrenut" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "Naziv zadatka koji je bio pokrenut" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "Pozicioni argumenti zadatka" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "JSON prikaz pozicionih argumenata koji se koriste sa zadatkom" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "Argumenti zadatka" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "JSON prikaz imenovanih argumenata koji se koriste sa zadatkom" + +#: documents/models.py:578 +msgid "Task State" +msgstr "Stanje zadatka" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "Trenutno stanje zadatka koji se izvršava" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "Datum i vreme kreiranja" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "Polje datuma i vremena kada je rezultat zadatka kreiran u UTC" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "Datum i vreme početka" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "Polje datuma i vremena kada je zadatak pokrenut u UTC" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "Datum i vreme završetka" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "Polje datuma i vremena kada je zadatak završen u UTC" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "Podaci o rezultatu" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "Podaci koje vraća zadatak" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "Komentar za dokument" + +#: documents/models.py:642 +msgid "comment" +msgstr "komentar" + +#: documents/models.py:643 +msgid "comments" +msgstr "komentari" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Nevažeći regularni izraz: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Nevažeća boja." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Vrsta datoteke %(type)s nije podržana" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Otkrivena je nevažeća promenljiva." @@ -444,87 +556,87 @@ msgstr "Lozinka" msgid "Sign in" msgstr "Prijavite se" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Engleski (US)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Beloruski" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Češki" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Danski" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Nemački" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Engleski (UK)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Španski" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Francuski" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italijanski" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Luksemburški" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Holandski" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Poljski" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugalski (Brazil)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugalski" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumunski" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Ruski" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slovenački" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Srpski" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Švedski" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Turski" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Kineski pojednostavljen" diff --git a/src/locale/sv_SE/LC_MESSAGES/django.po b/src/locale/sv_SE/LC_MESSAGES/django.po index 4ab73df08..32c79fec7 100644 --- a/src/locale/sv_SE/LC_MESSAGES/django.po +++ b/src/locale/sv_SE/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-08 22:07\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Swedish\n" "Language: sv_SE\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Dokument" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Valfritt ord" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Alla ord" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Exakt matchning" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Reguljära uttryck" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Ungefärligt ord" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Automatisk" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "namn" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "träff" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "matchande algoritm" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "är ej skiftlägeskänsligt" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "korrespondent" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "korrespondenter" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "färg" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "är inkorgsetikett" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Markerar denna etikett som en inkorgsetikett: Alla nyligen konsumerade dokument kommer att märkas med inkorgsetiketter." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "etikett" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "etiketter" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "dokumenttyp" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "dokumenttyper" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Okrypterad" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "Krypterad med GNU Privacy Guard" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "titel" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "innehåll" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Dokumentets obearbetade textdata. Detta fält används främst för sökning." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "MIME-typ" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "kontrollsumma" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Kontrollsumman för originaldokumentet." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "arkivera kontrollsumma" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Kontrollsumman för det arkiverade dokumentet." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "skapad" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "ändrad" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "lagringstyp" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "tillagd" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "filnamn" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Nuvarande filnamn i lagringsutrymmet" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "arkivfilnamn" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Nuvarande arkivfilnamn i lagringsutrymmet" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "serienummer (arkivering)" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Placeringen av detta dokument i ditt fysiska dokumentarkiv." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "dokument" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "dokument" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "felsök" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "varning" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "fel" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritisk" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "grupp" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "meddelande" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "nivå" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "logg" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "loggar" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "sparad vy" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "sparade vyer" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "användare" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "visa på kontrollpanelen" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "visa i sidofältet" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "sortera fält" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "sortera omvänt" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "titel innehåller" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "innehåll innehåller" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN är" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "korrespondent är" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "dokumenttyp är" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "är i inkorgen" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "har etikett" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "har någon etikett" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "skapad före" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "skapad efter" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "skapat år är" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "skapad månad är" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "skapad dag är" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "tillagd före" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "tillagd efter" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "ändrad före" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "ändrad efter" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "har inte etikett" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "har inte ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "titel eller innehåll innehåller" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "fulltextfråga" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "mer som detta" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "regeltyp" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "värde" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "filtrera regel" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "filtrera regler" -#: documents/models.py:521 -msgid "started" +#: documents/models.py:536 +msgid "Task ID" msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Ogiltigt reguljärt uttryck: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Ogiltig färg." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Filtypen %(type)s stöds inte" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "" @@ -444,87 +556,87 @@ msgstr "Lösenord" msgid "Sign in" msgstr "Logga in" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "Engelska (USA)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Tyska" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "Engelska (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "Spanska" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Franska" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "Italienska" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Holländska" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polska" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portugisiska (Brasilien)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portugisiska" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Rumänska" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Ryska" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "Svenska" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "" diff --git a/src/locale/tr_TR/LC_MESSAGES/django.po b/src/locale/tr_TR/LC_MESSAGES/django.po index 78b4d6f70..6e972d7fc 100644 --- a/src/locale/tr_TR/LC_MESSAGES/django.po +++ b/src/locale/tr_TR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-08-01 19:02\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "Belgeler" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "Herhangi bir kelime" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "Tüm Kelimeler" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "Tam eşleşme" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "Düzenli ifade" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "Fuzzy Kelime" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "Otomatik" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "ad" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "eşleme" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "eşleştirme algoritması" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "duyarsızdır" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "muhabir" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "muhabirler" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "renk" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "gelen kutu etiketidir" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "Bu etiketi, gelen kutusu etiketi olarak işaretle: Yeni aktarılan tüm dokümanlar gelen kutusu etiketi ile etiketlendirileceklerdir." -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "etiket" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "etiketler" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "belge türü" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "belge türleri" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "Şifresiz" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "GNU Gizlilik Koruması ile şifrelendirilmiştir" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "başlık" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "içerik" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "Belgenin ham, yalnızca metin verileri. Bu alan öncelikle arama için kullanılır." -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "mime türü" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "sağlama toplamı" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "Orjinal belgenin sağlama toplamı." -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "arşiv sağlama toplamı" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "Arşivlenen belgenin sağlama toplamı." -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "oluşturuldu" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "değiştirilmiş" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "depolama türü" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "eklendi" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "dosya adı" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "Depolamadaki geçerli dosya adı" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "arşiv dosya adı" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "Depolamadaki geçerli arşiv dosya adı" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "arşiv seri numarası" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "Bu belgenin fiziksel belge arşivinizdeki posizyonu." -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "belge" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "belgeler" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "hata ayıklama" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "bilgi" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "uyarı" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "hata" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "kritik" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "grup" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "mesaj" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "seviye" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "günlük" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "günlükler" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "kaydedilen görünüm" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "kaydedilen görünümler" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "kullanıcı" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "kontrol paneli'nde göster" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "kenar çubuğunda göster" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "alanı sıralama" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "tersine sırala" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "başlık içerir" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "içerik içerir" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN ise" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "muhabir ise" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "belge türü ise" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "gelen kutusunun içerisindedir" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "etiketine sahip" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "herhangi bir etiketine sahip" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "bu tarihten önce oluşturuldu" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "bu tarihten sonra oluşturuldu" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "oluşturma yili ise" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "oluşturma ayı ise" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "oluşturma günü ise" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "bu tarihten önce eklendi" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "bu tarihten sonra eklendi" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "bu tarihten önce değiştirldi" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "bu tarihten sonra değiştirldi" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "etikete sahip değil" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "ASN'e sahip değil" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "başlik veya içerik içerir" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "tam metin sorgulama" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "buna benzer daha" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "içerisinde etiketine sahip" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "kural türü" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "değer" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "filtreleme kuralı" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "filtreleme kuralları" -#: documents/models.py:521 -msgid "started" -msgstr "başladı" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "Hatalı Düzenli İfade: %(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "Geçersiz renk." -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "Dosya türü %(type)s desteklenmiyor" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "Geçersiz değişken algılandı." @@ -444,87 +556,87 @@ msgstr "Parola" msgid "Sign in" msgstr "Oturum aç" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "İngilizce (Birleşik Devletler)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "Belarusça" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "Çekçe" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "Danca" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "Almanca" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "İngilizce (GB)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "İspanyolca" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "Fransızca" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "İtalyanca" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "Lüksemburgca" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "Hollandaca" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "Polonyaca" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "Portekizce (Brezilya)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "Portekizce" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "Romence" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "Rusça" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "Slovakça" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "Sırpça" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "İsveççe" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "Türkçe" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "Basitleştirilmiş Çince" diff --git a/src/locale/zh_CN/LC_MESSAGES/django.po b/src/locale/zh_CN/LC_MESSAGES/django.po index 2a76b6cf3..67fc56899 100644 --- a/src/locale/zh_CN/LC_MESSAGES/django.po +++ b/src/locale/zh_CN/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-08 14:11-0700\n" -"PO-Revision-Date: 2022-07-15 04:02\n" +"POT-Creation-Date: 2022-11-09 21:50+0000\n" +"PO-Revision-Date: 2022-11-09 23:11\n" "Last-Translator: \n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" @@ -21,378 +21,490 @@ msgstr "" msgid "Documents" msgstr "文档" -#: documents/models.py:29 +#: documents/models.py:32 msgid "Any word" msgstr "任意单词" -#: documents/models.py:30 +#: documents/models.py:33 msgid "All words" msgstr "所有单词" -#: documents/models.py:31 +#: documents/models.py:34 msgid "Exact match" msgstr "精确匹配" -#: documents/models.py:32 +#: documents/models.py:35 msgid "Regular expression" msgstr "正则表达式" -#: documents/models.py:33 +#: documents/models.py:36 msgid "Fuzzy word" msgstr "模糊单词" -#: documents/models.py:34 +#: documents/models.py:37 msgid "Automatic" msgstr "自动" -#: documents/models.py:37 documents/models.py:354 paperless_mail/models.py:16 +#: documents/models.py:40 documents/models.py:367 paperless_mail/models.py:16 #: paperless_mail/models.py:80 msgid "name" msgstr "名称" -#: documents/models.py:39 +#: documents/models.py:42 msgid "match" msgstr "匹配" -#: documents/models.py:42 +#: documents/models.py:45 msgid "matching algorithm" msgstr "匹配算法" -#: documents/models.py:47 +#: documents/models.py:50 msgid "is insensitive" msgstr "忽略大小写" -#: documents/models.py:60 documents/models.py:115 +#: documents/models.py:63 documents/models.py:118 msgid "correspondent" msgstr "联系人" -#: documents/models.py:61 +#: documents/models.py:64 msgid "correspondents" msgstr "联系人" -#: documents/models.py:66 +#: documents/models.py:69 msgid "color" msgstr "颜色" -#: documents/models.py:69 +#: documents/models.py:72 msgid "is inbox tag" msgstr "收件箱标签" -#: documents/models.py:72 +#: documents/models.py:75 msgid "Marks this tag as an inbox tag: All newly consumed documents will be tagged with inbox tags." msgstr "将此标签标记为收件箱标签:所有新处理的文档将被标记为收件箱标签。" -#: documents/models.py:78 +#: documents/models.py:81 msgid "tag" msgstr "标签" -#: documents/models.py:79 documents/models.py:153 +#: documents/models.py:82 documents/models.py:156 msgid "tags" msgstr "标签" -#: documents/models.py:84 documents/models.py:135 +#: documents/models.py:87 documents/models.py:138 msgid "document type" msgstr "文档类型" -#: documents/models.py:85 +#: documents/models.py:88 msgid "document types" msgstr "文档类型" -#: documents/models.py:90 +#: documents/models.py:93 msgid "path" msgstr "路径" -#: documents/models.py:96 documents/models.py:124 +#: documents/models.py:99 documents/models.py:127 msgid "storage path" msgstr "保存路径" -#: documents/models.py:97 +#: documents/models.py:100 msgid "storage paths" msgstr "保存路径" -#: documents/models.py:105 +#: documents/models.py:108 msgid "Unencrypted" msgstr "未加密" -#: documents/models.py:106 +#: documents/models.py:109 msgid "Encrypted with GNU Privacy Guard" msgstr "使用 GNU 隐私防护(GPG)加密" -#: documents/models.py:127 +#: documents/models.py:130 msgid "title" msgstr "标题" -#: documents/models.py:139 +#: documents/models.py:142 documents/models.py:611 msgid "content" msgstr "内容" -#: documents/models.py:142 +#: documents/models.py:145 msgid "The raw, text-only data of the document. This field is primarily used for searching." msgstr "文档的原始、纯文本的数据。这个字段主要用于搜索。" -#: documents/models.py:147 +#: documents/models.py:150 msgid "mime type" msgstr "mime 类型" -#: documents/models.py:157 +#: documents/models.py:160 msgid "checksum" msgstr "校验和" -#: documents/models.py:161 +#: documents/models.py:164 msgid "The checksum of the original document." msgstr "原始文档的校验和。" -#: documents/models.py:165 +#: documents/models.py:168 msgid "archive checksum" msgstr "存档校验和" -#: documents/models.py:170 +#: documents/models.py:173 msgid "The checksum of the archived document." msgstr "已归档文档的校验和。" -#: documents/models.py:173 documents/models.py:335 documents/models.py:520 +#: documents/models.py:176 documents/models.py:348 documents/models.py:617 msgid "created" msgstr "已创建" -#: documents/models.py:176 +#: documents/models.py:179 msgid "modified" msgstr "已修改" -#: documents/models.py:183 +#: documents/models.py:186 msgid "storage type" msgstr "存储类型" -#: documents/models.py:191 +#: documents/models.py:194 msgid "added" msgstr "已添加" -#: documents/models.py:198 +#: documents/models.py:201 msgid "filename" msgstr "文件名" -#: documents/models.py:204 +#: documents/models.py:207 msgid "Current filename in storage" msgstr "当前存储中的文件名" -#: documents/models.py:208 +#: documents/models.py:211 msgid "archive filename" msgstr "归档文件名" -#: documents/models.py:214 +#: documents/models.py:217 msgid "Current archive filename in storage" msgstr "当前存储中的归档文件名" -#: documents/models.py:218 +#: documents/models.py:221 +msgid "original filename" +msgstr "" + +#: documents/models.py:227 +msgid "The original name of the file when it was uploaded" +msgstr "" + +#: documents/models.py:231 msgid "archive serial number" msgstr "归档序列号" -#: documents/models.py:224 +#: documents/models.py:237 msgid "The position of this document in your physical document archive." msgstr "此文档在您的物理文档归档中的位置。" -#: documents/models.py:230 +#: documents/models.py:243 documents/models.py:628 msgid "document" msgstr "文档" -#: documents/models.py:231 +#: documents/models.py:244 msgid "documents" msgstr "文档" -#: documents/models.py:318 +#: documents/models.py:331 msgid "debug" msgstr "调试" -#: documents/models.py:319 +#: documents/models.py:332 msgid "information" msgstr "信息" -#: documents/models.py:320 +#: documents/models.py:333 msgid "warning" msgstr "警告" -#: documents/models.py:321 +#: documents/models.py:334 msgid "error" msgstr "错误" -#: documents/models.py:322 +#: documents/models.py:335 msgid "critical" msgstr "严重" -#: documents/models.py:325 +#: documents/models.py:338 msgid "group" msgstr "用户组" -#: documents/models.py:327 +#: documents/models.py:340 msgid "message" msgstr "消息" -#: documents/models.py:330 +#: documents/models.py:343 msgid "level" msgstr "等级" -#: documents/models.py:339 +#: documents/models.py:352 msgid "log" msgstr "日志" -#: documents/models.py:340 +#: documents/models.py:353 msgid "logs" msgstr "日志" -#: documents/models.py:350 documents/models.py:403 +#: documents/models.py:363 documents/models.py:419 msgid "saved view" msgstr "保存的视图" -#: documents/models.py:351 +#: documents/models.py:364 msgid "saved views" msgstr "保存的视图" -#: documents/models.py:353 +#: documents/models.py:366 documents/models.py:637 msgid "user" msgstr "用户" -#: documents/models.py:357 +#: documents/models.py:370 msgid "show on dashboard" msgstr "在仪表盘显示" -#: documents/models.py:360 +#: documents/models.py:373 msgid "show in sidebar" msgstr "在侧边栏显示" -#: documents/models.py:364 +#: documents/models.py:377 msgid "sort field" msgstr "排序字段" -#: documents/models.py:369 +#: documents/models.py:382 msgid "sort reverse" msgstr "反向排序" -#: documents/models.py:374 +#: documents/models.py:387 msgid "title contains" msgstr "标题包含" -#: documents/models.py:375 +#: documents/models.py:388 msgid "content contains" msgstr "内容包含" -#: documents/models.py:376 +#: documents/models.py:389 msgid "ASN is" msgstr "ASN 为" -#: documents/models.py:377 +#: documents/models.py:390 msgid "correspondent is" msgstr "联系人是" -#: documents/models.py:378 +#: documents/models.py:391 msgid "document type is" msgstr "文档类型是" -#: documents/models.py:379 +#: documents/models.py:392 msgid "is in inbox" msgstr "在收件箱中" -#: documents/models.py:380 +#: documents/models.py:393 msgid "has tag" msgstr "有标签" -#: documents/models.py:381 +#: documents/models.py:394 msgid "has any tag" msgstr "有任意标签" -#: documents/models.py:382 +#: documents/models.py:395 msgid "created before" msgstr "在此时间之前创建" -#: documents/models.py:383 +#: documents/models.py:396 msgid "created after" msgstr "在此时间之后创建" -#: documents/models.py:384 +#: documents/models.py:397 msgid "created year is" msgstr "创建年份是" -#: documents/models.py:385 +#: documents/models.py:398 msgid "created month is" msgstr "创建月份是" -#: documents/models.py:386 +#: documents/models.py:399 msgid "created day is" msgstr "创建日期是" -#: documents/models.py:387 +#: documents/models.py:400 msgid "added before" msgstr "添加早于" -#: documents/models.py:388 +#: documents/models.py:401 msgid "added after" msgstr "添加晚于" -#: documents/models.py:389 +#: documents/models.py:402 msgid "modified before" msgstr "修改早于" -#: documents/models.py:390 +#: documents/models.py:403 msgid "modified after" msgstr "修改晚于" -#: documents/models.py:391 +#: documents/models.py:404 msgid "does not have tag" msgstr "没有标签" -#: documents/models.py:392 +#: documents/models.py:405 msgid "does not have ASN" msgstr "没有 ASN" -#: documents/models.py:393 +#: documents/models.py:406 msgid "title or content contains" msgstr "标题或内容包含" -#: documents/models.py:394 +#: documents/models.py:407 msgid "fulltext query" msgstr "全文检索" -#: documents/models.py:395 +#: documents/models.py:408 msgid "more like this" msgstr "更多类似内容" -#: documents/models.py:396 +#: documents/models.py:409 msgid "has tags in" msgstr "有标签包含于" -#: documents/models.py:406 +#: documents/models.py:410 +msgid "ASN greater than" +msgstr "" + +#: documents/models.py:411 +msgid "ASN less than" +msgstr "" + +#: documents/models.py:412 +msgid "storage path is" +msgstr "" + +#: documents/models.py:422 msgid "rule type" msgstr "规则类型" -#: documents/models.py:408 +#: documents/models.py:424 msgid "value" msgstr "值" -#: documents/models.py:411 +#: documents/models.py:427 msgid "filter rule" msgstr "过滤规则" -#: documents/models.py:412 +#: documents/models.py:428 msgid "filter rules" msgstr "过滤规则" -#: documents/models.py:521 -msgid "started" -msgstr "已开始" +#: documents/models.py:536 +msgid "Task ID" +msgstr "" -#: documents/serialisers.py:70 +#: documents/models.py:537 +msgid "Celery ID for the Task that was run" +msgstr "" + +#: documents/models.py:542 +msgid "Acknowledged" +msgstr "" + +#: documents/models.py:543 +msgid "If the task is acknowledged via the frontend or API" +msgstr "" + +#: documents/models.py:549 documents/models.py:556 +msgid "Task Name" +msgstr "" + +#: documents/models.py:550 +msgid "Name of the file which the Task was run for" +msgstr "" + +#: documents/models.py:557 +msgid "Name of the Task which was run" +msgstr "" + +#: documents/models.py:562 +msgid "Task Positional Arguments" +msgstr "" + +#: documents/models.py:564 +msgid "JSON representation of the positional arguments used with the task" +msgstr "" + +#: documents/models.py:569 +msgid "Task Named Arguments" +msgstr "" + +#: documents/models.py:571 +msgid "JSON representation of the named arguments used with the task" +msgstr "" + +#: documents/models.py:578 +msgid "Task State" +msgstr "" + +#: documents/models.py:579 +msgid "Current state of the task being run" +msgstr "" + +#: documents/models.py:584 +msgid "Created DateTime" +msgstr "" + +#: documents/models.py:585 +msgid "Datetime field when the task result was created in UTC" +msgstr "" + +#: documents/models.py:590 +msgid "Started DateTime" +msgstr "" + +#: documents/models.py:591 +msgid "Datetime field when the task was started in UTC" +msgstr "" + +#: documents/models.py:596 +msgid "Completed DateTime" +msgstr "" + +#: documents/models.py:597 +msgid "Datetime field when the task was completed in UTC" +msgstr "" + +#: documents/models.py:602 +msgid "Result Data" +msgstr "" + +#: documents/models.py:604 +msgid "The data returned by the task" +msgstr "" + +#: documents/models.py:613 +msgid "Comment for the document" +msgstr "" + +#: documents/models.py:642 +msgid "comment" +msgstr "" + +#: documents/models.py:643 +msgid "comments" +msgstr "" + +#: documents/serialisers.py:72 #, python-format msgid "Invalid regular expression: %(error)s" msgstr "无效的正则表达式:%(error)s" -#: documents/serialisers.py:191 +#: documents/serialisers.py:193 msgid "Invalid color." msgstr "无效的颜色" -#: documents/serialisers.py:515 +#: documents/serialisers.py:518 #, python-format msgid "File type %(type)s not supported" msgstr "不支持文件类型 %(type)s" -#: documents/serialisers.py:596 +#: documents/serialisers.py:599 msgid "Invalid variable detected." msgstr "检测到无效变量。" @@ -444,87 +556,87 @@ msgstr "密码" msgid "Sign in" msgstr "登录" -#: paperless/settings.py:339 +#: paperless/settings.py:378 msgid "English (US)" msgstr "英语(美国)" -#: paperless/settings.py:340 +#: paperless/settings.py:379 msgid "Belarusian" msgstr "白俄罗斯语" -#: paperless/settings.py:341 +#: paperless/settings.py:380 msgid "Czech" msgstr "捷克语" -#: paperless/settings.py:342 +#: paperless/settings.py:381 msgid "Danish" msgstr "丹麦语" -#: paperless/settings.py:343 +#: paperless/settings.py:382 msgid "German" msgstr "德语" -#: paperless/settings.py:344 +#: paperless/settings.py:383 msgid "English (GB)" msgstr "英语(英国)" -#: paperless/settings.py:345 +#: paperless/settings.py:384 msgid "Spanish" msgstr "西班牙语" -#: paperless/settings.py:346 +#: paperless/settings.py:385 msgid "French" msgstr "法语" -#: paperless/settings.py:347 +#: paperless/settings.py:386 msgid "Italian" msgstr "意大利语" -#: paperless/settings.py:348 +#: paperless/settings.py:387 msgid "Luxembourgish" msgstr "卢森堡语" -#: paperless/settings.py:349 +#: paperless/settings.py:388 msgid "Dutch" msgstr "荷兰语" -#: paperless/settings.py:350 +#: paperless/settings.py:389 msgid "Polish" msgstr "波兰语" -#: paperless/settings.py:351 +#: paperless/settings.py:390 msgid "Portuguese (Brazil)" msgstr "葡萄牙语 (巴西)" -#: paperless/settings.py:352 +#: paperless/settings.py:391 msgid "Portuguese" msgstr "葡萄牙语" -#: paperless/settings.py:353 +#: paperless/settings.py:392 msgid "Romanian" msgstr "罗马尼亚语" -#: paperless/settings.py:354 +#: paperless/settings.py:393 msgid "Russian" msgstr "俄语" -#: paperless/settings.py:355 +#: paperless/settings.py:394 msgid "Slovenian" msgstr "斯洛语尼亚语" -#: paperless/settings.py:356 +#: paperless/settings.py:395 msgid "Serbian" msgstr "塞尔维亚语" -#: paperless/settings.py:357 +#: paperless/settings.py:396 msgid "Swedish" msgstr "瑞典语" -#: paperless/settings.py:358 +#: paperless/settings.py:397 msgid "Turkish" msgstr "土耳其语" -#: paperless/settings.py:359 +#: paperless/settings.py:398 msgid "Chinese Simplified" msgstr "简体中文" diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 456e15745..c11e43489 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -8,6 +8,7 @@ import tempfile from typing import Final from typing import Optional from typing import Set +from typing import Tuple from urllib.parse import urlparse from celery.schedules import crontab @@ -65,6 +66,44 @@ def __get_path(key: str, default: str) -> str: return os.path.abspath(os.path.normpath(os.environ.get(key, default))) +def _parse_redis_url(env_redis: Optional[str]) -> Tuple[str]: + """ + Gets the Redis information from the environment or a default and handles + converting from incompatible django_channels and celery formats. + + Returns a tuple of (celery_url, channels_url) + """ + + # Not set, return a compatible default + if env_redis is None: + return ("redis://localhost:6379", "redis://localhost:6379") + + if "unix" in env_redis.lower(): + # channels_redis socket format, looks like: + # "unix:///path/to/redis.sock" + _, path = env_redis.split(":") + # Optionally setting a db number + if "?db=" in env_redis: + path, number = path.split("?db=") + return (f"redis+socket:{path}?virtual_host={number}", env_redis) + else: + return (f"redis+socket:{path}", env_redis) + + elif "+socket" in env_redis.lower(): + # celery socket style, looks like: + # "redis+socket:///path/to/redis.sock" + _, path = env_redis.split(":") + if "?virtual_host=" in env_redis: + # Virtual host (aka db number) + path, number = path.split("?virtual_host=") + return (env_redis, f"unix:{path}?db={number}") + else: + return (env_redis, f"unix:{path}") + + # Not a socket + return (env_redis, env_redis) + + # NEVER RUN WITH DEBUG IN PRODUCTION. DEBUG = __get_boolean("PAPERLESS_DEBUG", "NO") @@ -182,7 +221,9 @@ ASGI_APPLICATION = "paperless.asgi.application" STATIC_URL = os.getenv("PAPERLESS_STATIC_URL", BASE_URL + "static/") WHITENOISE_STATIC_PREFIX = "/static/" -_REDIS_URL = os.getenv("PAPERLESS_REDIS", "redis://localhost:6379") +_CELERY_REDIS_URL, _CHANNELS_REDIS_URL = _parse_redis_url( + os.getenv("PAPERLESS_REDIS", None), +) # TODO: what is this used for? TEMPLATES = [ @@ -205,7 +246,7 @@ CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { - "hosts": [_REDIS_URL], + "hosts": [_CHANNELS_REDIS_URL], "capacity": 2000, # default 100 "expiry": 15, # default 60 }, @@ -468,7 +509,7 @@ TASK_WORKERS = __get_int("PAPERLESS_TASK_WORKERS", 1) WORKER_TIMEOUT: Final[int] = __get_int("PAPERLESS_WORKER_TIMEOUT", 1800) -CELERY_BROKER_URL = _REDIS_URL +CELERY_BROKER_URL = _CELERY_REDIS_URL CELERY_TIMEZONE = TIME_ZONE CELERY_WORKER_HIJACK_ROOT_LOGGER = False @@ -513,7 +554,7 @@ CELERY_BEAT_SCHEDULE_FILENAME = os.path.join(DATA_DIR, "celerybeat-schedule.db") CACHES = { "default": { "BACKEND": "django.core.cache.backends.redis.RedisCache", - "LOCATION": _REDIS_URL, + "LOCATION": _CHANNELS_REDIS_URL, }, } diff --git a/src/paperless/tests/test_settings.py b/src/paperless/tests/test_settings.py index fed4079e2..71926542d 100644 --- a/src/paperless/tests/test_settings.py +++ b/src/paperless/tests/test_settings.py @@ -3,6 +3,7 @@ from unittest import mock from unittest import TestCase from paperless.settings import _parse_ignore_dates +from paperless.settings import _parse_redis_url from paperless.settings import default_threads_per_worker @@ -82,3 +83,59 @@ class TestIgnoreDateParsing(TestCase): self.assertGreaterEqual(default_threads, 1) self.assertLessEqual(default_workers * default_threads, i) + + def test_redis_socket_parsing(self): + """ + GIVEN: + - Various Redis connection URI formats + WHEN: + - The URI is parsed + THEN: + - Socket based URIs are translated + - Non-socket URIs are unchanged + - None provided uses default + """ + + for input, expected in [ + # Nothing is set + (None, ("redis://localhost:6379", "redis://localhost:6379")), + # celery style + ( + "redis+socket:///run/redis/redis.sock", + ( + "redis+socket:///run/redis/redis.sock", + "unix:///run/redis/redis.sock", + ), + ), + # redis-py / channels-redis style + ( + "unix:///run/redis/redis.sock", + ( + "redis+socket:///run/redis/redis.sock", + "unix:///run/redis/redis.sock", + ), + ), + # celery style with db + ( + "redis+socket:///run/redis/redis.sock?virtual_host=5", + ( + "redis+socket:///run/redis/redis.sock?virtual_host=5", + "unix:///run/redis/redis.sock?db=5", + ), + ), + # redis-py / channels-redis style with db + ( + "unix:///run/redis/redis.sock?db=10", + ( + "redis+socket:///run/redis/redis.sock?virtual_host=10", + "unix:///run/redis/redis.sock?db=10", + ), + ), + # Just a host with a port + ( + "redis://myredishost:6379", + ("redis://myredishost:6379", "redis://myredishost:6379"), + ), + ]: + result = _parse_redis_url(input) + self.assertTupleEqual(expected, result) diff --git a/src/paperless/urls.py b/src/paperless/urls.py index a57573e7a..a73720728 100644 --- a/src/paperless/urls.py +++ b/src/paperless/urls.py @@ -29,6 +29,8 @@ from paperless.consumers import StatusConsumer from paperless.views import FaviconView from paperless.views import GroupViewSet from paperless.views import UserViewSet +from paperless_mail.views import MailAccountViewSet +from paperless_mail.views import MailRuleViewSet from rest_framework.authtoken import views from rest_framework.routers import DefaultRouter @@ -43,6 +45,8 @@ api_router.register(r"storage_paths", StoragePathViewSet) api_router.register(r"tasks", TasksViewSet, basename="tasks") api_router.register(r"users", UserViewSet, basename="users") api_router.register(r"groups", GroupViewSet, basename="groups") +api_router.register(r"mail_accounts", MailAccountViewSet) +api_router.register(r"mail_rules", MailRuleViewSet) urlpatterns = [ diff --git a/src/paperless/version.py b/src/paperless/version.py index d196c358d..4778e14a6 100644 --- a/src/paperless/version.py +++ b/src/paperless/version.py @@ -1,7 +1,7 @@ from typing import Final from typing import Tuple -__version__: Final[Tuple[int, int, int]] = (1, 9, 2) +__version__: Final[Tuple[int, int, int]] = (1, 10, 2) # Version string like X.Y.Z __full_version_str__: Final[str] = ".".join(map(str, __version__)) # Version string like X.Y diff --git a/src/paperless_mail/admin.py b/src/paperless_mail/admin.py index 3b488b153..ce5341e4e 100644 --- a/src/paperless_mail/admin.py +++ b/src/paperless_mail/admin.py @@ -56,6 +56,7 @@ class MailRuleAdmin(admin.ModelAdmin): "filter_body", "filter_attachment_filename", "maximum_age", + "consumption_scope", "attachment_type", ), }, @@ -65,8 +66,8 @@ class MailRuleAdmin(admin.ModelAdmin): { "description": _( "The action applied to the mail. This action is only " - "performed when documents were consumed from the mail. " - "Mails without attachments will remain entirely untouched.", + "performed when the mail body or attachments were " + "consumed from the mail.", ), "fields": ("action", "action_parameter"), }, diff --git a/src/paperless_mail/apps.py b/src/paperless_mail/apps.py index 1c5d656e0..719400e76 100644 --- a/src/paperless_mail/apps.py +++ b/src/paperless_mail/apps.py @@ -1,8 +1,17 @@ from django.apps import AppConfig +from django.conf import settings from django.utils.translation import gettext_lazy as _ +from paperless_mail.signals import mail_consumer_declaration class PaperlessMailConfig(AppConfig): name = "paperless_mail" verbose_name = _("Paperless mail") + + def ready(self): + from documents.signals import document_consumer_declaration + + if settings.TIKA_ENABLED: + document_consumer_declaration.connect(mail_consumer_declaration) + AppConfig.ready(self) diff --git a/src/paperless_mail/mail.py b/src/paperless_mail/mail.py index 145aebec4..9ac03db6e 100644 --- a/src/paperless_mail/mail.py +++ b/src/paperless_mail/mail.py @@ -350,9 +350,16 @@ class MailAccountHandler(LoggingMixin): return total_processed_files - def handle_message(self, message, rule) -> int: - if not message.attachments: - return 0 + def handle_message(self, message, rule: MailRule) -> int: + processed_elements = 0 + + # Skip Message handling when only attachments are to be processed but + # message doesn't have any. + if ( + not message.attachments + and rule.consumption_scope == MailRule.ConsumptionScope.ATTACHMENTS_ONLY + ): + return processed_elements self.log( "debug", @@ -365,8 +372,41 @@ class MailAccountHandler(LoggingMixin): tag_ids = [tag.id for tag in rule.assign_tags.all()] doc_type = rule.assign_document_type - processed_attachments = 0 + if ( + rule.consumption_scope == MailRule.ConsumptionScope.EML_ONLY + or rule.consumption_scope == MailRule.ConsumptionScope.EVERYTHING + ): + processed_elements += self.process_eml( + message, + rule, + correspondent, + tag_ids, + doc_type, + ) + if ( + rule.consumption_scope == MailRule.ConsumptionScope.ATTACHMENTS_ONLY + or rule.consumption_scope == MailRule.ConsumptionScope.EVERYTHING + ): + processed_elements += self.process_attachments( + message, + rule, + correspondent, + tag_ids, + doc_type, + ) + + return processed_elements + + def process_attachments( + self, + message: MailMessage, + rule: MailRule, + correspondent, + tag_ids, + doc_type, + ): + processed_attachments = 0 for att in message.attachments: if ( @@ -436,5 +476,59 @@ class MailAccountHandler(LoggingMixin): f"since guessed mime type {mime_type} is not supported " f"by paperless", ) - return processed_attachments + + def process_eml( + self, + message: MailMessage, + rule: MailRule, + correspondent, + tag_ids, + doc_type, + ): + os.makedirs(settings.SCRATCH_DIR, exist_ok=True) + _, temp_filename = tempfile.mkstemp( + prefix="paperless-mail-", + dir=settings.SCRATCH_DIR, + suffix=".eml", + ) + with open(temp_filename, "wb") as f: + # Move "From"-header to beginning of file + # TODO: This ugly workaround is needed because the parser is + # chosen only by the mime_type detected via magic + # (see documents/consumer.py "mime_type = magic.from_file") + # Unfortunately magic sometimes fails to detect the mime + # type of .eml files correctly as message/rfc822 and instead + # detects text/plain. + # This also effects direct file consumption of .eml files + # which are not treated with this workaround. + from_element = None + for i, header in enumerate(message.obj._headers): + if header[0] == "From": + from_element = i + if from_element: + new_headers = [message.obj._headers.pop(from_element)] + new_headers += message.obj._headers + message.obj._headers = new_headers + + f.write(message.obj.as_bytes()) + + self.log( + "info", + f"Rule {rule}: " + f"Consuming eml from mail " + f"{message.subject} from {message.from_}", + ) + + consume_file.delay( + path=temp_filename, + override_filename=pathvalidate.sanitize_filename( + message.subject + ".eml", + ), + override_title=message.subject, + override_correspondent_id=correspondent.id if correspondent else None, + override_document_type_id=doc_type.id if doc_type else None, + override_tag_ids=tag_ids, + ) + processed_elements = 1 + return processed_elements diff --git a/src/paperless_mail/migrations/0016_mailrule_consumption_scope.py b/src/paperless_mail/migrations/0016_mailrule_consumption_scope.py new file mode 100644 index 000000000..ea54bce1b --- /dev/null +++ b/src/paperless_mail/migrations/0016_mailrule_consumption_scope.py @@ -0,0 +1,32 @@ +# Generated by Django 4.0.4 on 2022-07-11 22:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("paperless_mail", "0015_alter_mailrule_action"), + ] + + operations = [ + migrations.AddField( + model_name="mailrule", + name="consumption_scope", + field=models.PositiveIntegerField( + choices=[ + (1, "Only process attachments."), + ( + 2, + "Process full Mail (with embedded attachments in file) as .eml", + ), + ( + 3, + "Process full Mail (with embedded attachments in file) as .eml + process attachments as separate documents", + ), + ], + default=1, + verbose_name="consumption scope", + ), + ), + ] diff --git a/src/paperless_mail/models.py b/src/paperless_mail/models.py index 4c0a1a557..a7267cc06 100644 --- a/src/paperless_mail/models.py +++ b/src/paperless_mail/models.py @@ -56,6 +56,14 @@ class MailRule(models.Model): verbose_name = _("mail rule") verbose_name_plural = _("mail rules") + class ConsumptionScope(models.IntegerChoices): + ATTACHMENTS_ONLY = 1, _("Only process attachments.") + EML_ONLY = 2, _("Process full Mail (with embedded attachments in file) as .eml") + EVERYTHING = 3, _( + "Process full Mail (with embedded attachments in file) as .eml " + "+ process attachments as separate documents", + ) + class AttachmentProcessing(models.IntegerChoices): ATTACHMENTS_ONLY = 1, _("Only process attachments.") EVERYTHING = 2, _("Process all files, including 'inline' " "attachments.") @@ -145,6 +153,12 @@ class MailRule(models.Model): ), ) + consumption_scope = models.PositiveIntegerField( + _("consumption scope"), + choices=ConsumptionScope.choices, + default=ConsumptionScope.ATTACHMENTS_ONLY, + ) + action = models.PositiveIntegerField( _("action"), choices=MailAction.choices, diff --git a/src/paperless_mail/parsers.py b/src/paperless_mail/parsers.py new file mode 100644 index 000000000..d50217f2e --- /dev/null +++ b/src/paperless_mail/parsers.py @@ -0,0 +1,333 @@ +import os +import re +from html import escape +from io import BytesIO +from io import StringIO + +import requests +from bleach import clean +from bleach import linkify +from django.conf import settings +from documents.parsers import DocumentParser +from documents.parsers import make_thumbnail_from_pdf +from documents.parsers import ParseError +from humanfriendly import format_size +from imap_tools import MailMessage +from tika import parser + + +class MailDocumentParser(DocumentParser): + """ + This parser uses imap_tools to parse .eml files, generates pdf using + gotenbergs and sends the html part to a local tika server for text extraction. + """ + + gotenberg_server = settings.TIKA_GOTENBERG_ENDPOINT + tika_server = settings.TIKA_ENDPOINT + + logging_name = "paperless.parsing.mail" + _parsed = None + + def get_parsed(self, document_path) -> MailMessage: + if not self._parsed: + try: + with open(document_path, "rb") as eml: + self._parsed = MailMessage.from_bytes(eml.read()) + except Exception as err: + raise ParseError( + f"Could not parse {document_path}: {err}", + ) + if not self._parsed.from_values: + self._parsed = None + raise ParseError( + f"Could not parse {document_path}: Missing 'from'", + ) + + return self._parsed + + def get_thumbnail(self, document_path, mime_type, file_name=None): + if not self.archive_path: + self.archive_path = self.generate_pdf(document_path) + + return make_thumbnail_from_pdf( + self.archive_path, + self.tempdir, + self.logging_group, + ) + + def extract_metadata(self, document_path, mime_type): + result = [] + + try: + mail = self.get_parsed(document_path) + except ParseError as e: + self.log( + "warning", + f"Error while fetching document metadata for " f"{document_path}: {e}", + ) + return result + + for key, value in mail.headers.items(): + value = ", ".join(i for i in value) + + result.append( + { + "namespace": "", + "prefix": "header", + "key": key, + "value": value, + }, + ) + + result.append( + { + "namespace": "", + "prefix": "", + "key": "attachments", + "value": ", ".join( + f"{attachment.filename}" + f"({format_size(attachment.size, binary=True)})" + for attachment in mail.attachments + ), + }, + ) + + result.append( + { + "namespace": "", + "prefix": "", + "key": "date", + "value": mail.date.strftime("%Y-%m-%d %H:%M:%S %Z"), + }, + ) + + result.sort(key=lambda item: (item["prefix"], item["key"])) + return result + + def parse(self, document_path, mime_type, file_name=None): + def strip_text(text: str): + text = re.sub(r"\s+", " ", text) + text = re.sub(r"(\n *)+", "\n", text) + return text.strip() + + mail = self.get_parsed(document_path) + + self.text = f"Subject: {mail.subject}\n\n" + self.text += f"From: {mail.from_values.full}\n\n" + self.text += f"To: {', '.join(address.full for address in mail.to_values)}\n\n" + if len(mail.cc_values) >= 1: + self.text += ( + f"CC: {', '.join(address.full for address in mail.cc_values)}\n\n" + ) + if len(mail.bcc_values) >= 1: + self.text += ( + f"BCC: {', '.join(address.full for address in mail.bcc_values)}\n\n" + ) + if len(mail.attachments) >= 1: + att = [] + for a in mail.attachments: + att.append(f"{a.filename} ({format_size(a.size, binary=True)})") + + self.text += f"Attachments: {', '.join(att)}\n\n" + + if mail.html != "": + self.text += "HTML content: " + strip_text(self.tika_parse(mail.html)) + + self.text += f"\n\n{strip_text(mail.text)}" + + self.date = mail.date + self.archive_path = self.generate_pdf(document_path) + + def tika_parse(self, html: str): + self.log("info", "Sending content to Tika server") + + try: + parsed = parser.from_buffer(html, self.tika_server) + except Exception as err: + raise ParseError( + f"Could not parse content with tika server at " + f"{self.tika_server}: {err}", + ) + if parsed["content"]: + return parsed["content"] + else: + return "" + + def generate_pdf(self, document_path): + pdf_collection = [] + url_merge = self.gotenberg_server + "/forms/pdfengines/merge" + pdf_path = os.path.join(self.tempdir, "merged.pdf") + mail = self.get_parsed(document_path) + + pdf_collection.append(("1_mail.pdf", self.generate_pdf_from_mail(mail))) + + if mail.html == "": + with open(pdf_path, "wb") as file: + file.write(pdf_collection[0][1]) + file.close() + return pdf_path + else: + pdf_collection.append( + ( + "2_html.pdf", + self.generate_pdf_from_html(mail.html, mail.attachments), + ), + ) + + files = {} + for name, content in pdf_collection: + files[name] = (name, BytesIO(content)) + headers = {} + try: + response = requests.post(url_merge, files=files, headers=headers) + response.raise_for_status() # ensure we notice bad responses + except Exception as err: + raise ParseError(f"Error while converting document to PDF: {err}") + + with open(pdf_path, "wb") as file: + file.write(response.content) + file.close() + + return pdf_path + + @staticmethod + def mail_to_html(mail: MailMessage) -> StringIO: + data = {} + + def clean_html(text: str): + if isinstance(text, list): + text = "\n".join([str(e) for e in text]) + if type(text) != str: + text = str(text) + text = escape(text) + text = clean(text) + text = linkify(text, parse_email=True) + text = text.replace("\n", "
    ") + return text + + data["subject"] = clean_html(mail.subject) + if data["subject"] != "": + data["subject_label"] = "Subject" + data["from"] = clean_html(mail.from_values.full) + if data["from"] != "": + data["from_label"] = "From" + data["to"] = clean_html(", ".join(address.full for address in mail.to_values)) + if data["to"] != "": + data["to_label"] = "To" + data["cc"] = clean_html(", ".join(address.full for address in mail.cc_values)) + if data["cc"] != "": + data["cc_label"] = "CC" + data["bcc"] = clean_html(", ".join(address.full for address in mail.bcc_values)) + if data["bcc"] != "": + data["bcc_label"] = "BCC" + + att = [] + for a in mail.attachments: + att.append(f"{a.filename} ({format_size(a.size, binary=True)})") + data["attachments"] = clean_html(", ".join(att)) + if data["attachments"] != "": + data["attachments_label"] = "Attachments" + + data["date"] = clean_html(mail.date.astimezone().strftime("%Y-%m-%d %H:%M")) + data["content"] = clean_html(mail.text.strip()) + + html = StringIO() + + from django.template.loader import render_to_string + + rendered = render_to_string("email_msg_template.html", context=data) + + html.write(rendered) + html.seek(0) + + return html + + def generate_pdf_from_mail(self, mail): + + url = self.gotenberg_server + "/forms/chromium/convert/html" + self.log("info", "Converting mail to PDF") + + css_file = os.path.join(os.path.dirname(__file__), "templates/output.css") + + with open(css_file, "rb") as css_handle: + + files = { + "html": ("index.html", self.mail_to_html(mail)), + "css": ("output.css", css_handle), + } + headers = {} + data = { + "marginTop": "0.1", + "marginBottom": "0.1", + "marginLeft": "0.1", + "marginRight": "0.1", + "paperWidth": "8.27", + "paperHeight": "11.7", + "scale": "1.0", + } + try: + response = requests.post( + url, + files=files, + headers=headers, + data=data, + ) + response.raise_for_status() # ensure we notice bad responses + except Exception as err: + raise ParseError(f"Error while converting document to PDF: {err}") + + return response.content + + @staticmethod + def transform_inline_html(html, attachments): + def clean_html_script(text: str): + compiled_open = re.compile(re.escape("