mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-08-07 19:08:32 -05:00
Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
88042d7072 | ||
![]() |
bf92e52d5c | ||
![]() |
419580b3be | ||
![]() |
5ee1f6b82b | ||
![]() |
410bb6a84e | ||
![]() |
af2b5fef13 | ||
![]() |
372ac3a40c | ||
![]() |
a1507d6079 | ||
![]() |
9242a8901a | ||
![]() |
1d4f25f930 | ||
![]() |
7323ec8d16 | ||
![]() |
39d45367d0 | ||
![]() |
a6521952b0 | ||
![]() |
7148c10f1b | ||
![]() |
4a1a66248d | ||
![]() |
67d0773231 | ||
![]() |
ff370172b5 | ||
![]() |
1f707e86cc | ||
![]() |
a3dae02cfb | ||
![]() |
3eae8a2210 | ||
![]() |
0f18fe1853 | ||
![]() |
513c61eb79 | ||
![]() |
4031233fd4 | ||
![]() |
76ff6100a3 | ||
![]() |
05c36f91cf | ||
![]() |
6625f8962a | ||
![]() |
63402b70d2 | ||
![]() |
2ae4a7806d | ||
![]() |
fcc4ecd007 | ||
![]() |
45497250cd | ||
![]() |
7dd957140e | ||
![]() |
4cd772a39e | ||
![]() |
10bf9fd1f8 | ||
![]() |
bd8e68692e | ||
![]() |
b8386a1531 | ||
![]() |
61534fb29d | ||
![]() |
9ad81be38c | ||
![]() |
cf7048e336 | ||
![]() |
a6105b3ad3 |
37
.github/workflow-scripts/check-trailing-newline
vendored
Executable file
37
.github/workflow-scripts/check-trailing-newline
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Verify that all text files end in a trailing newline.
|
||||
|
||||
# Exit on first failing command.
|
||||
set -e
|
||||
|
||||
# Exit on unset variable.
|
||||
set -u
|
||||
|
||||
success=0
|
||||
|
||||
function is_plaintext_file() {
|
||||
local file="$1"
|
||||
if [[ $file == *.svg ]]; then
|
||||
echo ""
|
||||
return
|
||||
fi
|
||||
file --brief "${file}" | grep text
|
||||
}
|
||||
|
||||
# Split strings on newlines.
|
||||
IFS='
|
||||
'
|
||||
for file in $(git ls-files)
|
||||
do
|
||||
if [[ -z $(is_plaintext_file "${file}") ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! [[ -z "$(tail -c 1 "${file}")" ]]; then
|
||||
printf "File must end in a trailing newline: %s\n" "${file}" >&2
|
||||
success=255
|
||||
fi
|
||||
done
|
||||
|
||||
exit "${success}"
|
26
.github/workflow-scripts/check-trailing-whitespace
vendored
Executable file
26
.github/workflow-scripts/check-trailing-whitespace
vendored
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check for trailing whitespace at end of lines.
|
||||
|
||||
# Exit on first failing command.
|
||||
set -e
|
||||
# Exit on unset variable.
|
||||
set -u
|
||||
|
||||
FOUND_TRAILING_WHITESPACE=0
|
||||
|
||||
while read -r line; do
|
||||
if grep \
|
||||
"\s$" \
|
||||
--line-number \
|
||||
--with-filename \
|
||||
--binary-files=without-match \
|
||||
--exclude="*.svg" \
|
||||
--exclude="*.eps" \
|
||||
"${line}"; then
|
||||
echo "ERROR: Found trailing whitespace" >&2;
|
||||
FOUND_TRAILING_WHITESPACE=1
|
||||
fi
|
||||
done < <(git ls-files)
|
||||
|
||||
exit "${FOUND_TRAILING_WHITESPACE}"
|
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
@@ -81,6 +81,20 @@ jobs:
|
||||
run: |
|
||||
cd src/
|
||||
pycodestyle
|
||||
whitespace:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Ensure there are no trailing spaces
|
||||
run: |
|
||||
.github/workflow-scripts/check-trailing-whitespace
|
||||
-
|
||||
name: Ensure all text files end with a trailing newline
|
||||
run: |
|
||||
.github/workflow-scripts/check-trailing-whitespace
|
||||
|
||||
tests:
|
||||
runs-on: ubuntu-20.04
|
||||
@@ -158,7 +172,7 @@ jobs:
|
||||
path: src/documents/static/frontend/
|
||||
|
||||
build-release:
|
||||
needs: [frontend, documentation, tests, codestyle]
|
||||
needs: [frontend, documentation, tests, whitespace, codestyle]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
-
|
||||
@@ -268,7 +282,7 @@ jobs:
|
||||
build-docker-image:
|
||||
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/heads/feature-') || github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/ng-'))
|
||||
runs-on: ubuntu-latest
|
||||
needs: [frontend, tests, codestyle]
|
||||
needs: [frontend, tests, whitespace, codestyle]
|
||||
steps:
|
||||
-
|
||||
name: Prepare
|
||||
|
2
Pipfile
2
Pipfile
@@ -14,7 +14,7 @@ django = "~=3.2"
|
||||
django-cors-headers = "*"
|
||||
django-extensions = "*"
|
||||
django-filter = "~=2.4.0"
|
||||
django-q = "==1.3.4"
|
||||
django-q = "~=1.3.4"
|
||||
djangorestframework = "~=3.12.2"
|
||||
filelock = "*"
|
||||
fuzzywuzzy = {extras = ["speedup"], version = "*"}
|
||||
|
383
Pipfile.lock
generated
383
Pipfile.lock
generated
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "2da6572956d27205c496da2ef5f584a9ba53b5f6b3c8bf1724211dc48bfac7b7"
|
||||
"sha256": "deaa52fcf234236357749005f429cea100e817c694d8f383d931236e02e8bab0"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@@ -83,22 +83,31 @@
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c",
|
||||
"sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"
|
||||
"sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee",
|
||||
"sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"
|
||||
],
|
||||
"version": "==2020.12.5"
|
||||
"version": "==2021.5.30"
|
||||
},
|
||||
"cffi": {
|
||||
"hashes": [
|
||||
"sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813",
|
||||
"sha256:04c468b622ed31d408fea2346bec5bbffba2cc44226302a0de1ade9f5ea3d373",
|
||||
"sha256:06d7cd1abac2ffd92e65c0609661866709b4b2d82dd15f611e602b9b188b0b69",
|
||||
"sha256:06db6321b7a68b2bd6df96d08a5adadc1fa0e8f419226e25b2a5fbf6ccc7350f",
|
||||
"sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06",
|
||||
"sha256:0f861a89e0043afec2a51fd177a567005847973be86f709bbb044d7f42fc4e05",
|
||||
"sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea",
|
||||
"sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee",
|
||||
"sha256:1bf1ac1984eaa7675ca8d5745a8cb87ef7abecb5592178406e55858d411eadc0",
|
||||
"sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396",
|
||||
"sha256:24a570cd11895b60829e941f2613a4f79df1a27344cbbb82164ef2e0116f09c7",
|
||||
"sha256:24ec4ff2c5c0c8f9c6b87d5bb53555bf267e1e6f70e52e5a9740d32861d36b6f",
|
||||
"sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73",
|
||||
"sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315",
|
||||
"sha256:293e7ea41280cb28c6fcaaa0b1aa1f533b8ce060b9e701d78511e1e6c4a1de76",
|
||||
"sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1",
|
||||
"sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49",
|
||||
"sha256:3c3f39fa737542161d8b0d680df2ec249334cd70a8f420f71c9304bd83c3cbed",
|
||||
"sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892",
|
||||
"sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482",
|
||||
"sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058",
|
||||
@@ -107,6 +116,7 @@
|
||||
"sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53",
|
||||
"sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045",
|
||||
"sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3",
|
||||
"sha256:681d07b0d1e3c462dd15585ef5e33cb021321588bebd910124ef4f4fb71aef55",
|
||||
"sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5",
|
||||
"sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e",
|
||||
"sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c",
|
||||
@@ -125,8 +135,10 @@
|
||||
"sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e",
|
||||
"sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991",
|
||||
"sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6",
|
||||
"sha256:cc5a8e069b9ebfa22e26d0e6b97d6f9781302fe7f4f2b8776c3e1daea35f1adc",
|
||||
"sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1",
|
||||
"sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406",
|
||||
"sha256:df5052c5d867c1ea0b311fb7c3cd28b19df469c056f7fdcfe88c7473aa63e333",
|
||||
"sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d",
|
||||
"sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"
|
||||
],
|
||||
@@ -158,20 +170,19 @@
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:a3747c864f8e400a3664f5f4fd6dae11b4605bf6b727dae7b6f22ba9bd0a194a",
|
||||
"sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
|
||||
"sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
|
||||
"sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a",
|
||||
"sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==7.1.2"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==8.0.1"
|
||||
},
|
||||
"coloredlogs": {
|
||||
"hashes": [
|
||||
"sha256:5e78691e2673a8e294499e1832bb13efcfb44a86b92e18109fa18951093218ab",
|
||||
"sha256:b7f630a8297a66984b6bae0f6a1b0e0afb9f2f6838ea3bfa58f50d3d13e133d6"
|
||||
"sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934",
|
||||
"sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==15.0"
|
||||
"version": "==15.0.1"
|
||||
},
|
||||
"concurrent-log-handler": {
|
||||
"hashes": [
|
||||
@@ -225,11 +236,11 @@
|
||||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:13ac78dbfd189532cad8f383a27e58e18b3d33f80009ceb476d7fcbfc5dcebd8",
|
||||
"sha256:7e0a1393d18c16b503663752a8b6790880c5084412618990ce8a81cc908b4962"
|
||||
"sha256:66c9d8db8cc6fe938a28b7887c1596e42d522e27618562517cc8929eb7e7f296",
|
||||
"sha256:ea735cbbbb3b2fba6d4da4784a0043d84c67c92f1fdf15ad6db69900e792c10f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.2.3"
|
||||
"version": "==3.2.4"
|
||||
},
|
||||
"django-cors-headers": {
|
||||
"hashes": [
|
||||
@@ -265,11 +276,11 @@
|
||||
},
|
||||
"django-q": {
|
||||
"hashes": [
|
||||
"sha256:523d54dcf1b66152c1b658f914f00ed3b518a3432a9decd4898738ca8dbbe10f",
|
||||
"sha256:7e5c5c021a15cff6807044a3aa48f5757789ccfef839d71c575f5512931a3e33"
|
||||
"sha256:681c7e91c58322d0a4ea6d5fa8df21e6e785123fd6ee7c86af201e6a1c08ddc1",
|
||||
"sha256:db30266fadd6ab9336a8824291910ff1d1c28f7bc9d6e52cdaf33cc275ae6146"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.3.4"
|
||||
"version": "==1.3.8"
|
||||
},
|
||||
"djangorestframework": {
|
||||
"hashes": [
|
||||
@@ -365,33 +376,32 @@
|
||||
},
|
||||
"httptools": {
|
||||
"hashes": [
|
||||
"sha256:07659649fe6b3948b6490825f89abe5eb1cec79ebfaaa0b4bf30f3f33f3c2ba8",
|
||||
"sha256:08b79e09114e6ab5c3dbf560bba2cb2257ea38cdaeaf99b7cb80d8f92622fcd9",
|
||||
"sha256:1e35aa179b67086cc600a984924a88589b90793c9c1b260152ca4908786e09df",
|
||||
"sha256:31629e1f1b89959f8c0927bad12184dc07977dcf71e24f4772934aa490aa199b",
|
||||
"sha256:7792e70ead1d220142a99dde049fdbeddc66fe822953e085d02cd5155c38cdad",
|
||||
"sha256:851026bd63ec0af7e7592890d97d15c92b62d9e17094353f19a52c8e2b33710a",
|
||||
"sha256:8fcca4b7efe353b13a24017211334c57d055a6e132c7adffed13a10d28efca57",
|
||||
"sha256:9abd788465aa46a0f288bd3a99e53edd184177d6379e2098fd6097bb359ad9d6",
|
||||
"sha256:aebdf0bd7bf7c90ae6b3be458692bf6e9e5b610b501f9f74c7979015a51db4c4",
|
||||
"sha256:bda99a5723e7eab355ce57435c70853fc137a65aebf2f1cd4d15d96e2956da7b",
|
||||
"sha256:c1c63d860749841024951b0a78e4dec6f543d23751ef061d6ab60064c7b8b524",
|
||||
"sha256:c4111a0a8a00eff1e495d43ea5230aaf64968a48ddba8ea2d5f982efae827404",
|
||||
"sha256:dce59ee45dd6ee6c434346a5ac527c44014326f560866b4b2f414a692ee1aca8",
|
||||
"sha256:f759717ca1b2ef498c67ba4169c2b33eecf943a89f5329abcff8b89d153eb500",
|
||||
"sha256:f9545ff74bdf8a6e013ed18af3e24c656c06b6ca2441074be2f6cc28e24f48de",
|
||||
"sha256:fb7199b8fb0c50a22e77260bb59017e0c075fa80cb03bb2c8692de76e7bb7fe7",
|
||||
"sha256:fbf7ecd31c39728f251b1c095fd27c84e4d21f60a1d079a0333472ff3ae59d34"
|
||||
"sha256:01b392a166adcc8bc2f526a939a8aabf89fe079243e1543fd0e7dc1b58d737cb",
|
||||
"sha256:200fc1cdf733a9ff554c0bb97a4047785cfaad9875307d6087001db3eb2b417f",
|
||||
"sha256:3ab1f390d8867f74b3b5ee2a7ecc9b8d7f53750bd45714bf1cb72a953d7dfa77",
|
||||
"sha256:78d03dd39b09c99ec917d50189e6743adbfd18c15d5944392d2eabda688bf149",
|
||||
"sha256:79dbc21f3612a78b28384e989b21872e2e3cf3968532601544696e4ed0007ce5",
|
||||
"sha256:80ffa04fe8c8dfacf6e4cef8277347d35b0442c581f5814f3b0cf41b65c43c6e",
|
||||
"sha256:813871f961edea6cb2fe312f2d9b27d12a51ba92545380126f80d0de1917ea15",
|
||||
"sha256:94505026be56652d7a530ab03d89474dc6021019d6b8682281977163b3471ea0",
|
||||
"sha256:a23166e5ae2775709cf4f7ad4c2048755ebfb272767d244e1a96d55ac775cca7",
|
||||
"sha256:a289c27ccae399a70eacf32df9a44059ca2ba4ac444604b00a19a6c1f0809943",
|
||||
"sha256:a7594f9a010cdf1e16a58b3bf26c9da39bbf663e3b8d46d39176999d71816658",
|
||||
"sha256:b08d00d889a118f68f37f3c43e359aab24ee29eb2e3fe96d64c6a2ba8b9d6557",
|
||||
"sha256:cc9be041e428c10f8b6ab358c6b393648f9457094e1dcc11b4906026d43cd380",
|
||||
"sha256:d5682eeb10cca0606c4a8286a3391d4c3c5a36f0c448e71b8bd05be4e1694bfb",
|
||||
"sha256:dd38cad4599d58c23c01bca2102dcce30d61f6466328169bb17efb8a528f4d97",
|
||||
"sha256:fd3b8905e21431ad306eeaf56644a68fdd621bf8f3097eff54d0f6bdf7262065"
|
||||
],
|
||||
"version": "==0.1.2"
|
||||
"version": "==0.2.0"
|
||||
},
|
||||
"humanfriendly": {
|
||||
"hashes": [
|
||||
"sha256:066562956639ab21ff2676d1fda0b5987e985c534fc76700a19bd54bcb81121d",
|
||||
"sha256:d5c731705114b9ad673754f3317d9fa4c23212f36b29bdc4272a892eafc9bc72"
|
||||
"sha256:332da98c24cc150efcc91b5508b19115209272bfdf4b0764a56795932f854271",
|
||||
"sha256:f7dba53ac7935fd0b4a2fc9a29e316ddd9ea135fb3052d3d0279d10c18ff9c48"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==9.1"
|
||||
"version": "==9.2"
|
||||
},
|
||||
"hyperlink": {
|
||||
"hashes": [
|
||||
@@ -596,11 +606,11 @@
|
||||
},
|
||||
"ocrmypdf": {
|
||||
"hashes": [
|
||||
"sha256:3a757ac8bc4f822052a363c7fdc1e01e01033ae3e3398123990813eb6b3cf031",
|
||||
"sha256:c18db17e18984f540eaa774245571e3ec63a74f459b6029de561a06a77e78310"
|
||||
"sha256:17396579734b4a2e7b8e100a8a2f38a01a83adb949e2c87edd9e5433f8eb6932",
|
||||
"sha256:60079df8a0407e30b66b2828ffbf802bb8342d1198db41c27e4e2ef63efb06c3"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==12.0.1"
|
||||
"version": "==12.0.3"
|
||||
},
|
||||
"pathvalidate": {
|
||||
"hashes": [
|
||||
@@ -620,32 +630,34 @@
|
||||
},
|
||||
"pikepdf": {
|
||||
"hashes": [
|
||||
"sha256:087dc8e141dcfa0e76e93227a22f6b9cee000b3837b9e048ba96f389d0ee5d41",
|
||||
"sha256:1bcf4e45a831b302a0b6ae6cbd41aa6c81f95964b1d61e8da41186a4a779f701",
|
||||
"sha256:22d6615e742e7320a3a77148f65a8ba3591c054133faf6305a525c439b57cf38",
|
||||
"sha256:24d51dcc2d73e5d123acab4fef5d611f545ff2ce16c837d85833364d4d2cda45",
|
||||
"sha256:26a3af4845db89f364d18757978fad39ea852b6e7cae3137000a07c44d292b42",
|
||||
"sha256:36e9d557ef0505a6ec335faf9b2c93d4d062daa339dd1a6cbcda2a6dc886b38e",
|
||||
"sha256:417abdc29be8ddedabeb100a728b6525c5e1967ba47a03b9e0a81391efb4feb1",
|
||||
"sha256:5e71dcefdd889538a289cdaa2bb4559e4477e3f17846ffbdfad54b0e76443cf5",
|
||||
"sha256:62a6f2e2552bfd1bcd17b5e0e024db9ab7e93db39f43bb4246faff9b01154d47",
|
||||
"sha256:7a054701104c601d72b5ab8b3025a44b1b400f334ee7259dbd4bb1a2c24dad03",
|
||||
"sha256:7dcf6545c7deb2f6511a3b9220d56297b4165eeedc2eab785acba698cc9d95c0",
|
||||
"sha256:82da7b5d5a57e4704f7a81e75324b07b19577a96e06f5c5d8a89b29dec814766",
|
||||
"sha256:8cdafd18013b17f257655e95bfcb4ef14a7fc84a7334a9877b0532db4b55e3ff",
|
||||
"sha256:a0ff0291f74ef45dd2a1e1316b7d6464b996351365debbf611a5293cf2ff2562",
|
||||
"sha256:a2ef88f786aed79da559cd1a6a844f99e258971d64670bfba1efad96ed175fb0",
|
||||
"sha256:a84bbc7b3f9819c1541913bac2781da40d9506255c1cedb7233f9027ce23db92",
|
||||
"sha256:b1e0cfb6f5abe4d4863c55b2c9424340e5b44095789ef1368a0de99f8b4f852e",
|
||||
"sha256:ca8efe77f1f44d3c1c0d738407b87816f1445438aa6873d45e58fdd595e96c98",
|
||||
"sha256:d0f48252f23c128a3ddde16d98fa6567ac7fbce6792209771183b57c744106e1",
|
||||
"sha256:e1d988ddf063d6abf3d71e7c5bc46e5690fdcf0b06d7f00fced5d0b908f92267",
|
||||
"sha256:ec9d853c895693dd55b12ae37056808e192e5e2a8d2486cb30d19a5e7d6ff6a9",
|
||||
"sha256:fcbb6e37426564ccaf6bb301616700277d426225895b00a64283a95ff648f3b9",
|
||||
"sha256:ff29a8bd50f47554be7e062b3e1a2b466a7f567e1e49417dc62c3948b28304c7"
|
||||
"sha256:230f98284ae025e641472b5c23d83af3964717ef0fac79a072d05e12212d99f6",
|
||||
"sha256:23aff2408c169aff7f2453cc807b39427634df4fdbcc1217ff11e62984321772",
|
||||
"sha256:279cb9786c4757c36fa356214b012f766f3cfc834c6e2c6f661cd7fd1221fac7",
|
||||
"sha256:2bd8509ca04cfe3fa5c9ad17730eb43addd1b8f81604945c89f666ac3768fc19",
|
||||
"sha256:311e92958a75d8d73064b1ee1f280572aee03d03ee103ef77e989cc255acf2e9",
|
||||
"sha256:41e637ce69776990a0a170099000282cbcf7de94ab39a0194677366d923ff48d",
|
||||
"sha256:4a17030087da78287f3f18f90e4364b20cd1f3a8d511e5cc33171f9262d7dd6c",
|
||||
"sha256:4ee74e9b9277ae5327c8b19504b66eaa9a725fa4a6b2a23d161d3b2696f6c2e6",
|
||||
"sha256:59e7c6004d5eafff6d31d8185c5df6b8a2c3c7114c1d194edee520a9b608f09b",
|
||||
"sha256:5ff35499b1ae7b181277f78ce5b1bcc8d3009182bb389917791c5dc811fcc8e4",
|
||||
"sha256:60c1d6634e4b66636d731bee3615aa153a877983a499d3c5506f87c033a6d913",
|
||||
"sha256:77363eb0afcf7a8b8fe3aa9c3391cc12ad40e7e6be55a0b10b72bf70be6b2cbc",
|
||||
"sha256:838a386836c5d773029f04628ddab7131f6f7cfa3147382bf2a440143f4ef513",
|
||||
"sha256:9ad09d00186f172f247983d63f60d0572e1fb87b0ae30e3d504de451b8da8889",
|
||||
"sha256:9c885328d86d919b70decd3ef73ce42d76ab4b365ed3a851aef08e3f29e62c6e",
|
||||
"sha256:a25a12f2209a0378c57a8201c4add521ebb7cadd439e111cddb1532d347f0cd0",
|
||||
"sha256:a28e3472915d4881492ba6264f8db8ef3a4f382048dda307de5aa88a43b626d7",
|
||||
"sha256:b3ccde9aa84fd9663ecf3f39226372bc2c5311e9fabbab07955439c0deb1ecfa",
|
||||
"sha256:bbaafc08dd77c2e64a87dd6e377e4e8a7efd9a6d7de208ed8c5b908830465887",
|
||||
"sha256:c039ee6dcbf3f2054b8bddbff9f5002996d0d981d3d82ebe76041c237528aaef",
|
||||
"sha256:cee7a310e82e0a931b4805a1b25288efcb3f647f4d32c4107889a4b3fac4f159",
|
||||
"sha256:d245513995e0fe1e849fbb10e14061c229c59db9f8e346bfef4f2bf804847574",
|
||||
"sha256:db1f2a4b8fb4b91bf43ce8988f2f9d18ea36dbf7919d60a860e3fa68e1955a7e",
|
||||
"sha256:fb08ce0ec36c8571b167d9cd0fdad7b53b2f535cbd32c1e92f6f2883c353be7e",
|
||||
"sha256:fb0e1ceabaad4815efe23d1e19beaba33db38cf1e918011cd602cc0a43185056"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.12.0"
|
||||
"version": "==2.12.2"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
@@ -668,6 +680,7 @@
|
||||
"sha256:63728564c1410d99e6d1ae8e3b810fe012bc440952168af0a2877e8ff5ab96b9",
|
||||
"sha256:66cc56579fd91f517290ab02c51e3a80f581aba45fd924fcdee01fa06e635812",
|
||||
"sha256:6c32cc3145928c4305d142ebec682419a6c0a8ce9e33db900027ddca1ec39178",
|
||||
"sha256:8b56553c0345ad6dcb2e9b433ae47d67f95fc23fe28a0bde15a120f25257e291",
|
||||
"sha256:8bb1e155a74e1bfbacd84555ea62fa21c58e0b4e7e6b20e4447b8d07990ac78b",
|
||||
"sha256:95d5ef984eff897850f3a83883363da64aae1000e79cb3c321915468e8c6add5",
|
||||
"sha256:a013cbe25d20c2e0c4e85a9daf438f85121a4d0344ddc76e33fd7e3965d9af4b",
|
||||
@@ -832,11 +845,11 @@
|
||||
},
|
||||
"python-magic": {
|
||||
"hashes": [
|
||||
"sha256:8551e804c09a3398790bd9e392acb26554ae2609f29c72abb0b9dee9a5571eae",
|
||||
"sha256:ca884349f2c92ce830e3f498c5b7c7051fe2942c3ee4332f65213b8ebff15a62"
|
||||
"sha256:4fec8ee805fea30c07afccd1592c0f17977089895bdfaae5fec870a84e997626",
|
||||
"sha256:de800df9fb50f8ec5974761054a708af6e4246b03b4bdaee993f948947b0ebcf"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.4.22"
|
||||
"version": "==0.4.24"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
@@ -1062,10 +1075,10 @@
|
||||
},
|
||||
"sortedcontainers": {
|
||||
"hashes": [
|
||||
"sha256:37257a32add0a3ee490bb170b599e93095eed89a55da91fa9f48753ea12fd73f",
|
||||
"sha256:59cc937650cf60d677c16775597c89a960658a09cf7c1a668f86e1e4464b10a1"
|
||||
"sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88",
|
||||
"sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"
|
||||
],
|
||||
"version": "==2.3.0"
|
||||
"version": "==2.4.0"
|
||||
},
|
||||
"sqlparse": {
|
||||
"hashes": [
|
||||
@@ -1093,11 +1106,11 @@
|
||||
},
|
||||
"tqdm": {
|
||||
"hashes": [
|
||||
"sha256:daec693491c52e9498632dfbe9ccfc4882a557f5fa08982db1b4d3adbe0887c3",
|
||||
"sha256:ebdebdb95e3477ceea267decfc0784859aa3df3e27e22d23b83e9b272bf157ae"
|
||||
"sha256:24be966933e942be5f074c29755a95b315c69a91f839a29139bf26ffffe2d3fd",
|
||||
"sha256:aa0c29f03f298951ac6318f7c8ce584e48fa22ec26396e6411e43d038243bdb2"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.60.0"
|
||||
"version": "==4.61.1"
|
||||
},
|
||||
"twisted": {
|
||||
"extras": [
|
||||
@@ -1127,22 +1140,22 @@
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df",
|
||||
"sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"
|
||||
"sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c",
|
||||
"sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
|
||||
"version": "==1.26.4"
|
||||
"version": "==1.26.5"
|
||||
},
|
||||
"uvicorn": {
|
||||
"extras": [
|
||||
"standard"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:3292251b3c7978e8e4a7868f4baf7f7f7bb7e40c759ecc125c37e99cdea34202",
|
||||
"sha256:7587f7b08bd1efd2b9bad809a3d333e972f1d11af8a5e52a9371ee3a5de71524"
|
||||
"sha256:2a76bb359171a504b3d1c853409af3adbfa5cef374a4a59e5881945a97a93eae",
|
||||
"sha256:45ad7dfaaa7d55cab4cd1e85e03f27e9d60bc067ddc59db52a2b0aeca8870292"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.13.4"
|
||||
"version": "==0.14.0"
|
||||
},
|
||||
"uvloop": {
|
||||
"hashes": [
|
||||
@@ -1200,31 +1213,42 @@
|
||||
},
|
||||
"websockets": {
|
||||
"hashes": [
|
||||
"sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5",
|
||||
"sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5",
|
||||
"sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308",
|
||||
"sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb",
|
||||
"sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a",
|
||||
"sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c",
|
||||
"sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170",
|
||||
"sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422",
|
||||
"sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8",
|
||||
"sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485",
|
||||
"sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f",
|
||||
"sha256:745a1c8ca62f7d27de42b517ca7c6f716d1eb96c5aa73cf6407936c0167cbb3c",
|
||||
"sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8",
|
||||
"sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc",
|
||||
"sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779",
|
||||
"sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989",
|
||||
"sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1",
|
||||
"sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092",
|
||||
"sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824",
|
||||
"sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d",
|
||||
"sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55",
|
||||
"sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36",
|
||||
"sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"
|
||||
"sha256:0dd4eb8e0bbf365d6f652711ce21b8fd2b596f873d32aabb0fbb53ec604418cc",
|
||||
"sha256:1d0971cc7251aeff955aa742ec541ee8aaea4bb2ebf0245748fbec62f744a37e",
|
||||
"sha256:1d6b4fddb12ab9adf87b843cd4316c4bd602db8d5efd2fb83147f0458fe85135",
|
||||
"sha256:230a3506df6b5f446fed2398e58dcaafdff12d67fe1397dff196411a9e820d02",
|
||||
"sha256:276d2339ebf0df4f45df453923ebd2270b87900eda5dfd4a6b0cfa15f82111c3",
|
||||
"sha256:2cf04601633a4ec176b9cc3d3e73789c037641001dbfaf7c411f89cd3e04fcaf",
|
||||
"sha256:3ddff38894c7857c476feb3538dd847514379d6dc844961dc99f04b0384b1b1b",
|
||||
"sha256:48c222feb3ced18f3dc61168ca18952a22fb88e5eb8902d2bf1b50faefdc34a2",
|
||||
"sha256:51d04df04ed9d08077d10ccbe21e6805791b78eac49d16d30a1f1fe2e44ba0af",
|
||||
"sha256:597c28f3aa7a09e8c070a86b03107094ee5cdafcc0d55f2f2eac92faac8dc67d",
|
||||
"sha256:5c8f0d82ea2468282e08b0cf5307f3ad022290ed50c45d5cb7767957ca782880",
|
||||
"sha256:7189e51955f9268b2bdd6cc537e0faa06f8fffda7fb386e5922c6391de51b077",
|
||||
"sha256:7df3596838b2a0c07c6f6d67752c53859a54993d4f062689fdf547cb56d0f84f",
|
||||
"sha256:826ccf85d4514609219725ba4a7abd569228c2c9f1968e8be05be366f68291ec",
|
||||
"sha256:836d14eb53b500fd92bd5db2fc5894f7c72b634f9c2a28f546f75967503d8e25",
|
||||
"sha256:85db8090ba94e22d964498a47fdd933b8875a1add6ebc514c7ac8703eb97bbf0",
|
||||
"sha256:85e701a6c316b7067f1e8675c638036a796fe5116783a4c932e7eb8e305a3ffe",
|
||||
"sha256:8c941af1b20971d9e98c2369bdf118ef546b2569957469a9ab1e6d76b97d675f",
|
||||
"sha256:900589e19200be76dd7cbaa95e9771605b5ce3f62512d039fb3bc5da9014912a",
|
||||
"sha256:9147868bb0cc01e6846606cd65cbf9c58598f187b96d14dd1ca17338b08793bb",
|
||||
"sha256:9e7fdc775fe7403dbd8bc883ba59576a6232eac96dacb56512daacf7af5d618d",
|
||||
"sha256:ab5ee15d3462198c794c49ccd31773d8a2b8c17d622aa184f669d2b98c2f0857",
|
||||
"sha256:ad893d889bc700a5835e0a95a3e4f2c39e91577ab232a3dc03c262a0f8fc4b5c",
|
||||
"sha256:b2e71c4670ebe1067fa8632f0d081e47254ee2d3d409de54168b43b0ba9147e0",
|
||||
"sha256:b43b13e5622c5a53ab12f3272e6f42f1ce37cd5b6684b2676cb365403295cd40",
|
||||
"sha256:b4ad84b156cf50529b8ac5cc1638c2cf8680490e3fccb6121316c8c02620a2e4",
|
||||
"sha256:be5fd35e99970518547edc906efab29afd392319f020c3c58b0e1a158e16ed20",
|
||||
"sha256:caa68c95bc1776d3521f81eeb4d5b9438be92514ec2a79fececda814099c8314",
|
||||
"sha256:d144b350045c53c8ff09aa1cfa955012dd32f00c7e0862c199edcabb1a8b32da",
|
||||
"sha256:d2c2d9b24d3c65b5a02cac12cbb4e4194e590314519ed49db2f67ef561c3cf58",
|
||||
"sha256:e9e5fd6dbdf95d99bc03732ded1fc8ef22ebbc05999ac7e0c7bf57fe6e4e5ae2",
|
||||
"sha256:ebf459a1c069f9866d8569439c06193c586e72c9330db1390af7c6a0a32c4afd",
|
||||
"sha256:f31722f1c033c198aa4a39a01905951c00bd1c74f922e8afc1b1c62adbcdd56a",
|
||||
"sha256:f68c352a68e5fdf1e97288d5cec9296664c590c25932a8476224124aaf90dbcd"
|
||||
],
|
||||
"version": "==8.1"
|
||||
"version": "==9.1"
|
||||
},
|
||||
"whitenoise": {
|
||||
"hashes": [
|
||||
@@ -1343,10 +1367,10 @@
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c",
|
||||
"sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"
|
||||
"sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee",
|
||||
"sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"
|
||||
],
|
||||
"version": "==2020.12.5"
|
||||
"version": "==2021.5.30"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
@@ -1357,9 +1381,6 @@
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"coverage": {
|
||||
"extras": [
|
||||
"toml"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c",
|
||||
"sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6",
|
||||
@@ -1419,18 +1440,18 @@
|
||||
},
|
||||
"coveralls": {
|
||||
"hashes": [
|
||||
"sha256:7bd173b3425733661ba3063c88f180127cc2b20e9740686f86d2622b31b41385",
|
||||
"sha256:cbb942ae5ef3d2b55388cb5b43e93a269544911535f1e750e1c656aef019ce60"
|
||||
"sha256:172fb79c5f61c6ede60554f2cac46deff6d64ee735991fb2124fb414e188bdb4",
|
||||
"sha256:9b3236e086627340bf2c95f89f757d093cbed43d17179d3f4fb568c347e7d29a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.0.1"
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"distlib": {
|
||||
"hashes": [
|
||||
"sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb",
|
||||
"sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"
|
||||
"sha256:106fef6dc37dd8c0e2c0a60d3fca3e77460a48907f335fa28420463a6f799736",
|
||||
"sha256:23e223426b28491b1ced97dc3bbe183027419dfc7982b4fa2f05d5f3ff10711c"
|
||||
],
|
||||
"version": "==0.3.1"
|
||||
"version": "==0.3.2"
|
||||
},
|
||||
"docopt": {
|
||||
"hashes": [
|
||||
@@ -1449,11 +1470,11 @@
|
||||
},
|
||||
"execnet": {
|
||||
"hashes": [
|
||||
"sha256:7a13113028b1e1cc4c6492b28098b3c6576c9dccc7973bfe47b342afadafb2ac",
|
||||
"sha256:b73c5565e517f24b62dea8a5ceac178c661c4309d3aa0c3e420856c072c411b4"
|
||||
"sha256:7e3c2cdb6389542a91e9855a9cc7545fbed679e96f8808bcbb1beb325345b189",
|
||||
"sha256:e840ce25562e414ee5684864d510dbeeb0bce016bc89b22a6e5ce323b5e6552f"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==1.8.0"
|
||||
"version": "==1.8.1"
|
||||
},
|
||||
"factory-boy": {
|
||||
"hashes": [
|
||||
@@ -1465,11 +1486,11 @@
|
||||
},
|
||||
"faker": {
|
||||
"hashes": [
|
||||
"sha256:73562fb99b6046c5d26b8dd98a1437a896f8601c96382d835c656166159f4f59",
|
||||
"sha256:c6a4a0a1dde71f16d489a3097661a87ae96329dbde4c3ece8a5ccc340441ade1"
|
||||
"sha256:30189045769cb26f91ed218140469fd0b42520b2ea22ff2958ed81071a3ed839",
|
||||
"sha256:a724ca2325f4af659929052fbbb613caaec237a93fcdc1cbc7aa860e61e3c18f"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==8.1.4"
|
||||
"version": "==8.7.0"
|
||||
},
|
||||
"filelock": {
|
||||
"hashes": [
|
||||
@@ -1506,52 +1527,52 @@
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:2f2de5285cf37f33d33ecd4a9080b75c87cd0c1994d5a9c6df17131ea1f049c6",
|
||||
"sha256:ea8d7dd814ce9df6de6a761ec7f1cac98afe305b8cdc4aaae4e114b8d8ce24c5"
|
||||
"sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4",
|
||||
"sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.0.0"
|
||||
"version": "==3.0.1"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:007dc055dbce5b1104876acee177dbfd18757e19d562cd440182e1f492e96b95",
|
||||
"sha256:031bf79a27d1c42f69c276d6221172417b47cb4b31cdc73d362a9bf5a1889b9f",
|
||||
"sha256:161d575fa49395860b75da5135162481768b11208490d5a2143ae6785123e77d",
|
||||
"sha256:24bbc3507fb6dfff663af7900a631f2aca90d5a445f272db5fc84999fa5718bc",
|
||||
"sha256:2efaeb1baff547063bad2b2893a8f5e9c459c4624e1a96644bbba08910ae34e0",
|
||||
"sha256:31d4206caf9be06b8e7a85de4df933d159b4877d4fc308ca8192d97faf56a41e",
|
||||
"sha256:32200f562daaab472921a11cbb63780f1654552ae49518196fc361ed8e12e901",
|
||||
"sha256:3261fae28155e5c8634dd7710635fe540a05b58f160cef7713c7700cb9980e66",
|
||||
"sha256:3b54a9c68995ef4164567e2cd1a5e16db5dac30b2a50c39c82db8d4afaf14f63",
|
||||
"sha256:3c352ff634e289061711608f5e474ec38dbaa21e3e168820d53d5f4015e5b91b",
|
||||
"sha256:3fb47f97f1d338b943126e90b79cad50d4fcfa0b80637b5a9f468941dbbd9ce5",
|
||||
"sha256:441ce2a8c17683d97e06447fcbccbdb057cbf587c78eb75ae43ea7858042fe2c",
|
||||
"sha256:45535241baa0fc0ba2a43961a1ac7562ca3257f46c4c3e9c0de38b722be41bd1",
|
||||
"sha256:4aca81a687975b35e3e80bcf9aa93fe10cd57fac37bf18b2314c186095f57e05",
|
||||
"sha256:4cc563836f13c57f1473bc02d1e01fc37bab70ad4ee6be297d58c1d66bc819bf",
|
||||
"sha256:4fae0677f712ee090721d8b17f412f1cbceefbf0dc180fe91bab3232f38b4527",
|
||||
"sha256:58bc9fce3e1557d463ef5cee05391a05745fd95ed660f23c1742c711712c0abb",
|
||||
"sha256:664832fb88b8162268928df233f4b12a144a0c78b01d38b81bdcf0fc96668ecb",
|
||||
"sha256:70820a1c96311e02449591cbdf5cd1c6a34d5194d5b55094ab725364375c9eb2",
|
||||
"sha256:79b2ae94fa991be023832e6bcc00f41dbc8e5fe9d997a02db965831402551730",
|
||||
"sha256:83cf0228b2f694dcdba1374d5312f2277269d798e65f40344964f642935feac1",
|
||||
"sha256:87de598edfa2230ff274c4de7fcf24c73ffd96208c8e1912d5d0fee459767d75",
|
||||
"sha256:8f806bfd0f218477d7c46a11d3e52dc7f5fdfaa981b18202b7dc84bbc287463b",
|
||||
"sha256:90053234a6479738fd40d155268af631c7fca33365f964f2208867da1349294b",
|
||||
"sha256:a00dce2d96587651ef4fa192c17e039e8cfab63087c67e7d263a5533c7dad715",
|
||||
"sha256:a08cd07d3c3c17cd33d9e66ea9dee8f8fc1c48e2d11bd88fd2dc515a602c709b",
|
||||
"sha256:a19d39b02a24d3082856a5b06490b714a9d4179321225bbf22809ff1e1887cc8",
|
||||
"sha256:d00a669e4a5bec3ee6dbeeeedd82a405ced19f8aeefb109a012ea88a45afff96",
|
||||
"sha256:dab0c685f21f4a6c95bfc2afd1e7eae0033b403dd3d8c1b6d13a652ada75b348",
|
||||
"sha256:df561f65049ed3556e5b52541669310e88713fdae2934845ec3606f283337958",
|
||||
"sha256:e4570d16f88c7f3032ed909dc9e905a17da14a1c4cfd92608e3fda4cb1208bbd",
|
||||
"sha256:e77e4b983e2441aff0c0d07ee711110c106b625f440292dfe02a2f60c8218bd6",
|
||||
"sha256:e79212d09fc0e224d20b43ad44bb0a0a3416d1e04cf6b45fed265114a5d43d20",
|
||||
"sha256:f58b5ba13a5689ca8317b98439fccfbcc673acaaf8241c1869ceea40f5d585bf",
|
||||
"sha256:fef86115fdad7ae774720d7103aa776144cf9b66673b4afa9bcaa7af990ed07b"
|
||||
"sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298",
|
||||
"sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64",
|
||||
"sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b",
|
||||
"sha256:060b790af48b3d1cb6776a1e8956fb41106c6befaca717181c41a1728147dc73",
|
||||
"sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567",
|
||||
"sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff",
|
||||
"sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74",
|
||||
"sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35",
|
||||
"sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26",
|
||||
"sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7",
|
||||
"sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75",
|
||||
"sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f",
|
||||
"sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135",
|
||||
"sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8",
|
||||
"sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a",
|
||||
"sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914",
|
||||
"sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18",
|
||||
"sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8",
|
||||
"sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2",
|
||||
"sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d",
|
||||
"sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b",
|
||||
"sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f",
|
||||
"sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb",
|
||||
"sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833",
|
||||
"sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415",
|
||||
"sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902",
|
||||
"sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9",
|
||||
"sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d",
|
||||
"sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066",
|
||||
"sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f",
|
||||
"sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5",
|
||||
"sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94",
|
||||
"sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509",
|
||||
"sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51",
|
||||
"sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.0.0"
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
@@ -1611,19 +1632,19 @@
|
||||
},
|
||||
"pytest-cov": {
|
||||
"hashes": [
|
||||
"sha256:8535764137fecce504a49c2b742288e3d34bc09eed298ad65963616cc98fd45e",
|
||||
"sha256:95d4933dcbbacfa377bb60b29801daa30d90c33981ab2a79e9ab4452c165066e"
|
||||
"sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a",
|
||||
"sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.12.0"
|
||||
"version": "==2.12.1"
|
||||
},
|
||||
"pytest-django": {
|
||||
"hashes": [
|
||||
"sha256:80f8875226ec4dc0b205f0578072034563879d98d9b1bec143a80b9045716cb0",
|
||||
"sha256:a51150d8962200250e850c6adcab670779b9c2aa07271471059d1fb92a843fa9"
|
||||
"sha256:65783e78382456528bd9d79a35843adde9e6a47347b20464eb2c885cb0f1f606",
|
||||
"sha256:b5171e3798bf7e3fc5ea7072fe87324db67a4dd9f1192b037fed4cc3c1b7f455"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.2.0"
|
||||
"version": "==4.4.0"
|
||||
},
|
||||
"pytest-env": {
|
||||
"hashes": [
|
||||
@@ -1730,11 +1751,11 @@
|
||||
},
|
||||
"sphinxcontrib-htmlhelp": {
|
||||
"hashes": [
|
||||
"sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f",
|
||||
"sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b"
|
||||
"sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07",
|
||||
"sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==1.0.3"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"sphinxcontrib-jsmath": {
|
||||
"hashes": [
|
||||
@@ -1754,11 +1775,11 @@
|
||||
},
|
||||
"sphinxcontrib-serializinghtml": {
|
||||
"hashes": [
|
||||
"sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc",
|
||||
"sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"
|
||||
"sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd",
|
||||
"sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==1.1.4"
|
||||
"version": "==1.1.5"
|
||||
},
|
||||
"termcolor": {
|
||||
"hashes": [
|
||||
@@ -1792,19 +1813,19 @@
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df",
|
||||
"sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"
|
||||
"sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c",
|
||||
"sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
|
||||
"version": "==1.26.4"
|
||||
"version": "==1.26.5"
|
||||
},
|
||||
"virtualenv": {
|
||||
"hashes": [
|
||||
"sha256:307a555cf21e1550885c82120eccaf5acedf42978fd362d32ba8410f9593f543",
|
||||
"sha256:72cf267afc04bf9c86ec932329b7e94db6a0331ae9847576daaa7ca3c86b29a4"
|
||||
"sha256:14fdf849f80dbb29a4eb6caa9875d476ee2a5cf76a5f5415fa2f1606010ab467",
|
||||
"sha256:2b0126166ea7c9c3661f5b8e06773d28f83322de7a3ff7d06f0aed18c9de6a76"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==20.4.6"
|
||||
"version": "==20.4.7"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -100,6 +100,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. Updated to work with 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.
|
||||
|
||||
These projects also exist, but their status and compatibility with paperless-ng is unknown.
|
||||
|
||||
|
@@ -12,27 +12,29 @@ Note that this role requires root access, so either run it in a playbook with a
|
||||
|
||||
- hosts: all
|
||||
roles:
|
||||
- role: ansible
|
||||
- role: paperless-ng
|
||||
become: yes
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
Most configuration variables from paperless-ng itself are available and accept their respective arguments.
|
||||
Every `PAPERLESS_*` configuration varaible is lowercased and instead prefixed with `paperlessng_*` in `defaults/main.yml`.
|
||||
Every `PAPERLESS_*` configuration variable is lowercased and instead prefixed with `paperlessng_*` in `defaults/main.yml`.
|
||||
|
||||
For a full listing including explainations and allowed values, see the current [documentation](https://paperless-ng.readthedocs.io/en/ng-0.9.14/configuration.html).
|
||||
For a full listing including explanations and allowed values, see the current [documentation](https://paperless-ng.readthedocs.io/en/latest/configuration.html).
|
||||
|
||||
Additional variables available in this role are listed below, along with default values:
|
||||
|
||||
paperlessng_version: 0.9.14
|
||||
paperlessng_version: latest
|
||||
|
||||
The [release](https://github.com/jonaswinkler/paperless-ng/releases) archive version of paperless-ng to install.
|
||||
`latest` stands for the latest release of paperless-ng.
|
||||
To install a specific version of paperless-ng, use the tag name of the release, e. g. `ng-1.4.4`, or specify a branch or commit id.
|
||||
|
||||
paperlessng_redis_host: localhost
|
||||
paperlessng_redis_port: 6379
|
||||
|
||||
Seperate configuration values that combine into `PAPERLESS_REDIS`.
|
||||
Separate configuration values that combine into `PAPERLESS_REDIS`.
|
||||
|
||||
paperlessng_db_type: sqlite
|
||||
|
||||
@@ -96,11 +98,11 @@ Example Playbook
|
||||
- hosts: all
|
||||
become: yes
|
||||
vars_files:
|
||||
- vars/main.yml
|
||||
- vars/paperless-ng.yml
|
||||
roles:
|
||||
- ansible
|
||||
- paperless-ng
|
||||
|
||||
`vars/main.yml`:
|
||||
`vars/paperless-ng.yml`:
|
||||
|
||||
paperlessng_media_root: /mnt/media/smbshare
|
||||
|
||||
|
@@ -1 +1 @@
|
||||
COMPOSE_PROJECT_NAME=paperless
|
||||
COMPOSE_PROJECT_NAME=paperless
|
||||
|
@@ -29,13 +29,9 @@ initialize() {
|
||||
mkdir -p /tmp/paperless
|
||||
|
||||
set +e
|
||||
CURRENT_USER=$(stat -c '%U' ../)
|
||||
CURRENT_GROUP=$(stat -c '%G' ../)
|
||||
if [[ ${CURRENT_USER} != "paperless" || ${CURRENT_GROUP} != "paperless" ]] ; then
|
||||
echo "Adjusting permissions of paperless files. This may take a while."
|
||||
chown -R paperless:paperless ../
|
||||
fi
|
||||
echo "Adjusting permissions of paperless files. This may take a while."
|
||||
chown -R paperless:paperless /tmp/paperless
|
||||
find .. -not \( -user paperless -and -group paperless \) -exec chown paperless:paperless {} +
|
||||
set -e
|
||||
|
||||
gosu paperless /sbin/docker-prepare.sh
|
||||
|
@@ -149,22 +149,15 @@ Ansible Route
|
||||
|
||||
Most of the update process is automated when using the ansible role.
|
||||
|
||||
1. Backup your defined role variables file outside the paperless source-tree:
|
||||
1. Update the role to the target release tag to make sure the ansible scripts are compatible:
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
$ cp ansible/vars.yml ~/vars.yml.old
|
||||
$ ansible-galaxy install git+https://github.com/jonaswinkler/paperless-ng.git,master --force
|
||||
|
||||
2. Pull the release tag you want to update to:
|
||||
2. Update the role variable definitions ``vars/paperless-ng.yml`` (where appropriate).
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
$ git fetch --all
|
||||
$ git checkout ng-0.9.14
|
||||
|
||||
3. Update the role variable definitions ``ansible/vars.yml`` (where appropriate).
|
||||
|
||||
4. Run the ansible playbook you created created during :ref:`installation <setup-ansible>` again:
|
||||
3. Run the ansible playbook you created created during :ref:`installation <setup-ansible>` again:
|
||||
|
||||
.. note::
|
||||
|
||||
|
@@ -5,6 +5,19 @@
|
||||
Changelog
|
||||
*********
|
||||
|
||||
paperless-ng 1.4.5
|
||||
##################
|
||||
|
||||
This is a maintenance release.
|
||||
|
||||
* Updated Python and Angular dependencies.
|
||||
* Changed the algorithm that changes permissions during startup. This is still fast,
|
||||
and will hopefully cause less issues.
|
||||
* Fixed an issue that would sometimes cause paperless to write an incomplete
|
||||
classification model file to disk.
|
||||
* Fixed an issue with the OCRmyPDF parser that would always try to extract text
|
||||
with PDFminer even from non-PDF files.
|
||||
|
||||
paperless-ng 1.4.4
|
||||
##################
|
||||
|
||||
@@ -25,7 +38,7 @@ paperless-ng 1.4.3
|
||||
* `Michael Shamoon`_ added dark mode for the login and logout pages.
|
||||
* `Alexander Menk`_ added additional stylesheets for printing. You can now print any page of paperless and the print result will hide the page header, sidebar, and action buttons.
|
||||
* Added support for sorting when using full text search.
|
||||
|
||||
|
||||
* Fixes
|
||||
|
||||
* `puuu`_ fixed ``PAPERLESS_FORCE_SCRIPT_NAME``. You can now host paperless on sub paths such as ``https://localhost:8000/paperless/``.
|
||||
|
@@ -174,11 +174,11 @@ PAPERLESS_AUTO_LOGIN_USERNAME=<username>
|
||||
Defaults to none, which disables this feature.
|
||||
|
||||
PAPERLESS_ADMIN_USER=<username>
|
||||
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 seperately, such as Kubernetes
|
||||
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 seperately, such as Kubernetes
|
||||
or AWS ECS.
|
||||
|
||||
|
||||
Requires `PAPERLESS_ADMIN_PASSWORD` to be set.
|
||||
|
||||
.. note::
|
||||
@@ -188,7 +188,7 @@ PAPERLESS_ADMIN_USER=<username>
|
||||
the lifecycle of the containers.
|
||||
|
||||
PAPERLESS_ADMIN_MAIL=<email>
|
||||
(Optional) Specify superuser email address. Only used when
|
||||
(Optional) Specify superuser email address. Only used when
|
||||
`PAPERLESS_ADMIN_USER` is set.
|
||||
|
||||
Defaults to ``root@localhost``.
|
||||
@@ -222,17 +222,17 @@ PAPERLESS_ENABLE_HTTP_REMOTE_USER=<bool>
|
||||
Also see the warning `in the official documentation <https://docs.djangoproject.com/en/3.1/howto/auth-remote-user/#configuration>`.
|
||||
|
||||
Defaults to `false` which disables this feature.
|
||||
|
||||
|
||||
PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME=<str>
|
||||
If `PAPERLESS_ENABLE_HTTP_REMOTE_USER` is enabled, this property allows to
|
||||
customize the name of the HTTP header from which the authenticated username
|
||||
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
|
||||
Thus, the configured value must start with `HTTP_` followed by the
|
||||
normalized actual header name.
|
||||
|
||||
|
||||
Defaults to `HTTP_REMOTE_USER`.
|
||||
|
||||
|
||||
.. _configuration-ocr:
|
||||
|
||||
OCR settings
|
||||
@@ -622,6 +622,14 @@ PAPERLESS_IGNORE_DATES=<string>
|
||||
|
||||
Defaults to an empty string to not ignore any dates.
|
||||
|
||||
PAPERLESS_DATE_ORDER=<format>
|
||||
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.
|
||||
|
||||
|
||||
|
||||
Binaries
|
||||
########
|
||||
|
@@ -6,7 +6,7 @@ Contributing to Paperless
|
||||
.. warning::
|
||||
|
||||
This section is not updated to paperless-ng yet.
|
||||
|
||||
|
||||
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 Free software is that you can see what's wrong and help to get it
|
||||
|
@@ -23,10 +23,10 @@ Apart from that, the folder structure is as follows:
|
||||
* ``scripts/`` - Various scripts that help with different parts of development.
|
||||
* ``docker/`` - Files required to build the docker image.
|
||||
|
||||
Initial setup and first start
|
||||
Initial setup and first start
|
||||
=============================
|
||||
|
||||
After you forked and cloned the code from github you need to perform a first-time setup.
|
||||
After you forked and cloned the code from github you need to perform a first-time setup.
|
||||
To do the setup you need to perform the steps from the following chapters in a certain order:
|
||||
|
||||
1. Install prerequisites + pipenv as mentioned in :ref:`Bare metal route <setup-bare_metal>`
|
||||
@@ -35,19 +35,19 @@ To do the setup you need to perform the steps from the following chapters in a c
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
$ npm install -g @angular/cli
|
||||
$ npm install -g @angular/cli
|
||||
|
||||
4. Create ``consume`` and ``media`` folders in the cloned root folder.
|
||||
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
mkdir -p consume media
|
||||
|
||||
5. You can now either ...
|
||||
|
||||
* install redis or
|
||||
* install redis or
|
||||
* use the included scripts/start-services.sh to use docker to fire up a redis instance (and some other services such as tika, gotenberg and a postgresql server) or
|
||||
* spin up a bare redis container
|
||||
* spin up a bare redis container
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
@@ -79,7 +79,7 @@ To do the setup you need to perform the steps from the following chapters in a c
|
||||
python3 manage.py runserver & python3 manage.py document_consumer & python3 manage.py qcluster
|
||||
|
||||
10. Login with the superuser credentials provided in step 8 at ``http://localhost:8000`` to create a session that enables you to use the backend.
|
||||
|
||||
|
||||
Backend development environment is now ready, to start Frontend development go to ``/src-ui`` and run ``ng serve``. From there you can use ``http://localhost:4200`` for a preview.
|
||||
|
||||
Back end development
|
||||
@@ -207,7 +207,7 @@ Adding new languages requires adding the translated files in the "src-ui/src/loc
|
||||
// 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":
|
||||
@@ -320,7 +320,7 @@ methods ``parse`` and ``get_thumbnail``. You can provide your own implementation
|
||||
|
||||
# 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")
|
||||
|
||||
|
@@ -68,10 +68,10 @@ 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-ng on Raspberry Pi?*
|
||||
|
||||
|
@@ -49,7 +49,7 @@ resources in the documentation:
|
||||
paperless-ng.
|
||||
* Paperless is now integrated with a
|
||||
:ref:`task processing queue <setup-task_processor>` that tells you
|
||||
at a glance when and why something is not working.
|
||||
at a glance when and why something is not working.
|
||||
* The :ref:`changelog <paperless_changelog>` contains a detailed list of all changes
|
||||
in paperless-ng.
|
||||
|
||||
|
@@ -116,9 +116,7 @@ performs all the steps described in :ref:`setup-docker_hub` automatically.
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
$ wget https://raw.githubusercontent.com/jonaswinkler/paperless-ng/master/install-paperless-ng.sh
|
||||
$ chmod +x install-paperless-ng.sh
|
||||
$ ./install-paperless-ng.sh
|
||||
$ curl -L https://raw.githubusercontent.com/jonaswinkler/paperless-ng/master/install-paperless-ng.sh | bash
|
||||
|
||||
.. _setup-docker_hub:
|
||||
|
||||
@@ -286,7 +284,7 @@ writing. Windows is not and will never be supported.
|
||||
|
||||
Use this list for your preferred package management:
|
||||
|
||||
.. code::
|
||||
.. code::
|
||||
|
||||
python3 python3-pip python3-dev imagemagick fonts-liberation optipng gnupg libpq-dev libmagic-dev mime-support
|
||||
|
||||
@@ -305,7 +303,7 @@ writing. Windows is not and will never be supported.
|
||||
|
||||
Use this list for your preferred package management:
|
||||
|
||||
.. code::
|
||||
.. code::
|
||||
|
||||
unpaper ghostscript icc-profiles-free qpdf liblept5 libxml2 pngquant zlib1g tesseract-ocr
|
||||
|
||||
@@ -361,7 +359,7 @@ writing. Windows is not and will never be supported.
|
||||
|
||||
8. Install python requirements from the ``requirements.txt`` file.
|
||||
It is up to you if you wish to use a virtual environment or not. First you should update your pip, so it gets the actual packages.
|
||||
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
sudo -Hu paperless pip3 install --upgrade pip
|
||||
|
@@ -81,7 +81,7 @@ 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.
|
||||
@@ -200,13 +200,13 @@ This might have multiple reasons.
|
||||
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
|
||||
|
@@ -71,7 +71,7 @@ your documents:
|
||||
|
||||
This process can be configured to fit your needs. If you don't want paperless
|
||||
to create archived versions for digital documents, you can configure that by
|
||||
configuring ``PAPERLESS_OCR_MODE=skip_noarchive``. Please read the
|
||||
configuring ``PAPERLESS_OCR_MODE=skip_noarchive``. Please read the
|
||||
:ref:`relevant section in the documentation <configuration-ocr>`.
|
||||
|
||||
.. note::
|
||||
@@ -289,7 +289,7 @@ Matching specific tags, correspondents or types:
|
||||
Matching dates:
|
||||
|
||||
.. code::
|
||||
|
||||
|
||||
created:[2005 to 2009]
|
||||
added:yesterday
|
||||
modified:today
|
||||
@@ -306,11 +306,11 @@ Matching inexact words:
|
||||
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.
|
||||
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>`_.
|
||||
|
||||
|
||||
|
||||
.. _usage-recommended_workflow:
|
||||
|
||||
@@ -385,7 +385,7 @@ Once you have scanned in a document, proceed in paperless as follows.
|
||||
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
|
||||
|
@@ -15,13 +15,13 @@ attrs==21.2.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2,
|
||||
autobahn==21.3.1; python_version >= '3.7'
|
||||
automat==20.2.0
|
||||
blessed==1.18.0
|
||||
certifi==2020.12.5
|
||||
certifi==2021.5.30
|
||||
cffi==1.14.5
|
||||
channels-redis==3.2.0
|
||||
channels==3.0.3
|
||||
chardet==4.0.0; python_version >= '3.1'
|
||||
click==7.1.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
|
||||
coloredlogs==15.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
|
||||
click==8.0.1; python_version >= '3.6'
|
||||
coloredlogs==15.0.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
|
||||
concurrent-log-handler==0.9.19
|
||||
constantly==15.1.0
|
||||
cryptography==3.4.7
|
||||
@@ -31,16 +31,16 @@ django-cors-headers==3.7.0
|
||||
django-extensions==3.1.3
|
||||
django-filter==2.4.0
|
||||
django-picklefield==3.0.1; python_version >= '3'
|
||||
django-q==1.3.4
|
||||
django==3.2.3
|
||||
django-q==1.3.8
|
||||
django==3.2.4
|
||||
djangorestframework==3.12.4
|
||||
filelock==3.0.12
|
||||
fuzzywuzzy[speedup]==0.18.0
|
||||
gunicorn==20.1.0
|
||||
h11==0.12.0; python_version >= '3.6'
|
||||
hiredis==2.0.0; python_version >= '3.6'
|
||||
httptools==0.1.2
|
||||
humanfriendly==9.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
|
||||
httptools==0.2.0
|
||||
humanfriendly==9.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
|
||||
hyperlink==21.0.0
|
||||
idna==2.10; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
|
||||
imap-tools==0.41.0
|
||||
@@ -53,10 +53,10 @@ langdetect==1.0.9
|
||||
lxml==4.6.3; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
|
||||
msgpack==1.0.2
|
||||
numpy==1.19.5
|
||||
ocrmypdf==12.0.1
|
||||
ocrmypdf==12.0.3
|
||||
pathvalidate==2.4.1
|
||||
pdfminer.six==20201018
|
||||
pikepdf==2.12.0
|
||||
pikepdf==2.12.2
|
||||
pillow==8.2.0
|
||||
pluggy==0.13.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
|
||||
portalocker==2.3.0; python_version >= '3'
|
||||
@@ -69,7 +69,7 @@ python-dateutil==2.8.1
|
||||
python-dotenv==0.17.1
|
||||
python-gnupg==0.4.7
|
||||
python-levenshtein==0.12.2
|
||||
python-magic==0.4.22
|
||||
python-magic==0.4.24
|
||||
pytz==2021.1
|
||||
pyyaml==5.4.1
|
||||
redis==3.5.3
|
||||
@@ -80,21 +80,21 @@ scikit-learn==0.24.0
|
||||
scipy==1.5.4
|
||||
service-identity==21.1.0
|
||||
six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
|
||||
sortedcontainers==2.3.0
|
||||
sortedcontainers==2.4.0
|
||||
sqlparse==0.4.1; python_version >= '3.5'
|
||||
threadpoolctl==2.1.0; python_version >= '3.5'
|
||||
tika==1.24
|
||||
tqdm==4.60.0
|
||||
tqdm==4.61.1
|
||||
twisted[tls]==21.2.0; python_full_version >= '3.5.4'
|
||||
txaio==21.2.1; python_version >= '3.6'
|
||||
tzlocal==2.1
|
||||
urllib3==1.26.4; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'
|
||||
uvicorn[standard]==0.13.4
|
||||
urllib3==1.26.5; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'
|
||||
uvicorn[standard]==0.14.0
|
||||
uvloop==0.14.0
|
||||
watchdog==1.0.2
|
||||
watchgod==0.7
|
||||
wcwidth==0.2.5
|
||||
websockets==8.1
|
||||
websockets==9.1
|
||||
whitenoise==5.2.0
|
||||
whoosh==2.7.4
|
||||
zope.interface==5.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
|
||||
|
@@ -72,7 +72,6 @@
|
||||
"optimization": true,
|
||||
"outputHashing": "none",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
|
@@ -33,4 +33,4 @@ exports.config = {
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
25149
src-ui/package-lock.json
generated
25149
src-ui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -11,41 +11,41 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~10.1.5",
|
||||
"@angular/common": "~10.1.5",
|
||||
"@angular/compiler": "~10.1.5",
|
||||
"@angular/core": "~10.1.5",
|
||||
"@angular/forms": "~10.1.5",
|
||||
"@angular/localize": "~10.1.5",
|
||||
"@angular/platform-browser": "~10.1.5",
|
||||
"@angular/platform-browser-dynamic": "~10.1.5",
|
||||
"@angular/router": "~10.1.5",
|
||||
"@ng-bootstrap/ng-bootstrap": "^8.0.4",
|
||||
"@ng-select/ng-select": "^5.0.9",
|
||||
"@angular/animations": "~11.2.14",
|
||||
"@angular/common": "~11.2.14",
|
||||
"@angular/compiler": "~11.2.14",
|
||||
"@angular/core": "~11.2.14",
|
||||
"@angular/forms": "~11.2.14",
|
||||
"@angular/localize": "~11.2.14",
|
||||
"@angular/platform-browser": "~11.2.14",
|
||||
"@angular/platform-browser-dynamic": "~11.2.14",
|
||||
"@angular/router": "~11.2.14",
|
||||
"@ng-bootstrap/ng-bootstrap": "^9.1.2",
|
||||
"@ng-select/ng-select": "^7.0.0",
|
||||
"bootstrap": "^4.5.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"ng-bootstrap": "^1.6.3",
|
||||
"ng2-pdf-viewer": "^6.3.2",
|
||||
"ngx-bootstrap": "^6.2.0",
|
||||
"ngx-color": "^6.2.0",
|
||||
"ngx-cookie-service": "^10.1.1",
|
||||
"ngx-file-drop": "^10.0.0",
|
||||
"ngx-file-drop": "^11.1.0",
|
||||
"ngx-infinite-scroll": "^9.1.0",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.0.0",
|
||||
"uuid": "^8.3.1",
|
||||
"zone.js": "~0.10.2"
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^0.1002.0",
|
||||
"@angular/cli": "~10.1.5",
|
||||
"@angular/compiler-cli": "~10.1.5",
|
||||
"@types/jasmine": "~3.5.0",
|
||||
"@angular-devkit/build-angular": "~0.1102.13",
|
||||
"@angular/cli": "~11.2.14",
|
||||
"@angular/compiler-cli": "~11.2.14",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"karma": "~5.0.0",
|
||||
"karma": "~6.3.3",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
@@ -53,6 +53,6 @@
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.3.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.0.2"
|
||||
"typescript": "~4.1.5"
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ const routes: Routes = [
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
|
@@ -1,3 +1,3 @@
|
||||
<app-toasts></app-toasts>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
<router-outlet></router-outlet>
|
||||
|
@@ -45,7 +45,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
ngOnInit(): void {
|
||||
this.consumerStatusService.connect()
|
||||
|
||||
|
||||
|
||||
this.successSubscription = this.consumerStatusService.onDocumentConsumptionFinished().subscribe(status => {
|
||||
if (this.showNotification(SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS)) {
|
||||
this.toastService.show({title: $localize`Document added`, delay: 10000, content: $localize`Document ${status.filename} was added to paperless.`, actionName: $localize`Open document`, action: () => {
|
||||
|
@@ -30,7 +30,7 @@ export class ConfirmDialogComponent implements OnInit {
|
||||
|
||||
@Input()
|
||||
buttonsEnabled = true
|
||||
|
||||
|
||||
confirmButtonEnabled = true
|
||||
seconds = 0
|
||||
|
||||
|
@@ -55,7 +55,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -83,7 +83,7 @@ export class FilterableDropdownSelectionModel {
|
||||
if (fireEvent) {
|
||||
this.changed.next(this)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private getNonTemporary(id: number) {
|
||||
|
@@ -10,7 +10,7 @@
|
||||
<path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8z"/>
|
||||
</svg>
|
||||
</ng-container>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="mr-1">
|
||||
<app-tag *ngIf="isTag; else displayName" [tag]="item" [clickable]="true" linkTitle="Filter by tag"></app-tag>
|
||||
|
@@ -11,7 +11,7 @@ export class AbstractInputComponent<T> implements OnInit, ControlValueAccessor {
|
||||
constructor() { }
|
||||
|
||||
onChange = (newValue: T) => {};
|
||||
|
||||
|
||||
onTouched = () => {};
|
||||
|
||||
writeValue(newValue: any): void {
|
||||
|
@@ -2,4 +2,4 @@
|
||||
<input type="checkbox" class="custom-control-input" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" (blur)="onTouched()" [disabled]="disabled">
|
||||
<label class="custom-control-label" [for]="inputId">{{title}}</label>
|
||||
<small *ngIf="hint" class="form-text text-muted">{{hint}}</small>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -15,7 +15,7 @@ import { AbstractInputComponent } from '../abstract-input';
|
||||
})
|
||||
export class CheckComponent extends AbstractInputComponent<boolean> {
|
||||
|
||||
constructor() {
|
||||
constructor() {
|
||||
super()
|
||||
}
|
||||
|
||||
|
@@ -5,12 +5,12 @@
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" [style.background-color]="value"> </span>
|
||||
</div>
|
||||
|
||||
|
||||
<ng-template #popContent>
|
||||
<div style="min-width: 200px;" class="pb-3">
|
||||
<color-slider [color]="value" (onChangeComplete)="colorChanged($event.color.hex)"></color-slider>
|
||||
</div>
|
||||
|
||||
|
||||
</ng-template>
|
||||
|
||||
<input class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [autoClose]="'outside'" [ngbPopover]="popContent" placement="bottom" popoverClass="shadow">
|
||||
@@ -30,4 +30,4 @@
|
||||
<div class="invalid-feedback">
|
||||
{{error}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -11,4 +11,4 @@
|
||||
</div>
|
||||
<small *ngIf="hint" class="form-text text-muted">{{hint}}</small>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -5,4 +5,4 @@
|
||||
<div class="invalid-feedback">
|
||||
{{error}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -12,4 +12,4 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-dark" (click)="cancelClicked()" i18n>Cancel</button>
|
||||
<button type="button" class="btn btn-primary" (click)="selectClicked.emit(selected)" i18n>Select</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,2 +1,2 @@
|
||||
<span *ngIf="!clickable" class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</span>
|
||||
<a [routerLink]="" [title]="linkTitle" *ngIf="clickable" class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</a>
|
||||
<a [routerLink]="" [title]="linkTitle" *ngIf="clickable" class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</a>
|
||||
|
@@ -23,7 +23,7 @@ export class StatisticsWidgetComponent implements OnInit, OnDestroy {
|
||||
statistics: Statistics = {}
|
||||
|
||||
subscription: Subscription
|
||||
|
||||
|
||||
private getStatistics(): Observable<Statistics> {
|
||||
return this.http.get(`${environment.apiBaseUrl}statistics/`)
|
||||
}
|
||||
|
@@ -13,4 +13,4 @@
|
||||
<p i18n>Consult the documentation on how to use these features. The section on basic usage also has some information on how to use paperless in general.</p>
|
||||
</ng-container>
|
||||
|
||||
</app-widget-frame>
|
||||
</app-widget-frame>
|
||||
|
@@ -4,9 +4,9 @@
|
||||
<h5 class="card-title mb-0">{{title}}</h5>
|
||||
<ng-content select ="[header-buttons]"></ng-content>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="card-body text-dark">
|
||||
<ng-content select ="[content]"></ng-content>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -20,4 +20,4 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,3 +1,3 @@
|
||||
.metadata-column {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
@@ -64,4 +64,4 @@
|
||||
span ::ng-deep .match {
|
||||
color: black;
|
||||
background-color: rgb(255, 211, 66);
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<div class="form-inline d-flex align-items-center">
|
||||
<div class="input-group input-group-sm flex-fill w-auto">
|
||||
<div class="input-group-prepend" ngbDropdown>
|
||||
<button class="btn btn-outline-primary" ngbDropdownToggle>{{textFilterTargetName}}</button>
|
||||
<button class="btn btn-outline-primary" ngbDropdownToggle>{{textFilterTargetName}}</button>
|
||||
<div class="dropdown-menu shadow" ngbDropdownMenu>
|
||||
<button *ngFor="let t of textFilterTargets" ngbDropdownItem [class.active]="textFilterTarget == t.id" (click)="changeTextFilterTarget(t.id)">{{t.name}}</button>
|
||||
</div>
|
||||
|
@@ -32,6 +32,6 @@ export class CorrespondentEditDialogComponent extends EditDialogComponent<Paperl
|
||||
match: new FormControl(""),
|
||||
is_insensitive: new FormControl(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ export class CorrespondentListComponent extends GenericListComponent<PaperlessCo
|
||||
constructor(correspondentsService: CorrespondentService, modalService: NgbModal,
|
||||
private list: DocumentListViewService,
|
||||
toastService: ToastService
|
||||
) {
|
||||
) {
|
||||
super(correspondentsService,modalService,CorrespondentEditDialogComponent, toastService)
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,7 @@ import { ToastService } from 'src/app/services/toast.service';
|
||||
})
|
||||
export class DocumentTypeEditDialogComponent extends EditDialogComponent<PaperlessDocumentType> {
|
||||
|
||||
constructor(service: DocumentTypeService, activeModal: NgbActiveModal, toastService: ToastService) {
|
||||
constructor(service: DocumentTypeService, activeModal: NgbActiveModal, toastService: ToastService) {
|
||||
super(service, activeModal, toastService)
|
||||
}
|
||||
|
||||
|
@@ -49,4 +49,4 @@
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
@@ -52,4 +52,4 @@
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
@@ -5,4 +5,4 @@
|
||||
<path d="M7 6.5C7 7.328 6.552 8 6 8s-1-.672-1-1.5S5.448 5 6 5s1 .672 1 1.5zm4 0c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S9.448 5 10 5s1 .672 1 1.5z"/>
|
||||
</svg>
|
||||
<h1 i18n>404 Not Found</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -6,7 +6,7 @@ export function cloneFilterRules(filterRules: FilterRule[]): FilterRule[] {
|
||||
for (let rule of filterRules) {
|
||||
newRules.push({rule_type: rule.rule_type, value: rule.value})
|
||||
}
|
||||
return newRules
|
||||
return newRules
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
@@ -19,4 +19,4 @@ export function isFullTextFilterRule(filterRules: FilterRule[]): boolean {
|
||||
export interface FilterRule {
|
||||
rule_type: number
|
||||
value: string
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { MatchingModel } from './matching-model';
|
||||
|
||||
export interface PaperlessCorrespondent extends MatchingModel {
|
||||
|
||||
|
||||
last_correspondence?: Date
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
export interface PaperlessDocumentMetadata {
|
||||
|
||||
|
||||
original_checksum?: string
|
||||
|
||||
archived_checksum?: string
|
||||
@@ -10,4 +10,4 @@ export interface PaperlessDocumentMetadata {
|
||||
|
||||
has_archive_version?: boolean
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -6,4 +6,4 @@ export interface PaperlessDocumentSuggestions {
|
||||
|
||||
document_types?: number[]
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -15,4 +15,4 @@ export interface PaperlessSavedView extends ObjectWithId {
|
||||
|
||||
filter_rules: FilterRule[]
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -3,5 +3,5 @@ export interface Results<T> {
|
||||
count: number
|
||||
|
||||
results: T[]
|
||||
|
||||
|
||||
}
|
||||
|
@@ -8,4 +8,4 @@ export interface WebsocketConsumerStatusMessage {
|
||||
message?: string
|
||||
document_id: number
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ export class ApiVersionInterceptor implements HttpInterceptor {
|
||||
'Accept': `application/json; version=${environment.apiVersion}`
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
return next.handle(request);
|
||||
}
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ export class CsrfInterceptor implements HttpInterceptor {
|
||||
let prefix = ""
|
||||
if (this.meta.getTag('name=cookie_prefix')) {
|
||||
prefix = this.meta.getTag('name=cookie_prefix').content
|
||||
}
|
||||
}
|
||||
let csrfToken = this.cookieService.get(`${prefix?prefix:''}csrftoken`)
|
||||
if (csrfToken) {
|
||||
request = request.clone({
|
||||
|
@@ -11,12 +11,11 @@ const FORMAT_TO_ISO_FORMAT = {
|
||||
@Pipe({
|
||||
name: 'customDate'
|
||||
})
|
||||
export class CustomDatePipe extends DatePipe implements PipeTransform {
|
||||
export class CustomDatePipe implements PipeTransform {
|
||||
|
||||
private defaultLocale: string
|
||||
|
||||
constructor(@Inject(LOCALE_ID) locale: string, private settings: SettingsService) {
|
||||
super(locale)
|
||||
constructor(@Inject(LOCALE_ID) locale: string, private datePipe: DatePipe, private settings: SettingsService) {
|
||||
this.defaultLocale = locale
|
||||
}
|
||||
|
||||
@@ -24,9 +23,9 @@ export class CustomDatePipe extends DatePipe implements PipeTransform {
|
||||
let l = locale || this.settings.get(SETTINGS_KEYS.DATE_LOCALE) || this.defaultLocale
|
||||
let f = format || this.settings.get(SETTINGS_KEYS.DATE_FORMAT)
|
||||
if (l == "iso-8601") {
|
||||
return super.transform(value, FORMAT_TO_ISO_FORMAT[f], timezone)
|
||||
return this.datePipe.transform(value, FORMAT_TO_ISO_FORMAT[f], timezone)
|
||||
} else {
|
||||
return super.transform(value, format || this.settings.get(SETTINGS_KEYS.DATE_FORMAT), timezone, l)
|
||||
return this.datePipe.transform(value, format || this.settings.get(SETTINGS_KEYS.DATE_FORMAT), timezone, l)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* https://gist.github.com/JonCatmull/ecdf9441aaa37336d9ae2c7f9cb7289a
|
||||
*
|
||||
*
|
||||
* @license
|
||||
* Copyright (c) 2019 Jonathan Catmull.
|
||||
*
|
||||
|
@@ -16,4 +16,4 @@ export class SafePipe implements PipeTransform {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ export class OpenDocumentsService {
|
||||
|
||||
private MAX_OPEN_DOCUMENTS = 5
|
||||
|
||||
constructor(private documentService: DocumentService) {
|
||||
constructor(private documentService: DocumentService) {
|
||||
if (sessionStorage.getItem(OPEN_DOCUMENT_SERVICE.DOCUMENTS)) {
|
||||
try {
|
||||
this.openDocuments = JSON.parse(sessionStorage.getItem(OPEN_DOCUMENT_SERVICE.DOCUMENTS))
|
||||
|
@@ -44,7 +44,7 @@ export class SavedViewService extends AbstractPaperlessService<PaperlessSavedVie
|
||||
tap(() => this.reload())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
patchMany(objects: PaperlessSavedView[]): Observable<PaperlessSavedView[]> {
|
||||
return combineLatest(objects.map(o => super.patch(o))).pipe(
|
||||
tap(() => this.reload())
|
||||
|
@@ -10,10 +10,10 @@ import { DocumentService } from './document.service';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SearchService {
|
||||
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
autocomplete(term: string): Observable<string[]> {
|
||||
return this.http.get<string[]>(`${environment.apiBaseUrl}search/autocomplete/`, {params: new HttpParams().set('term', term)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ function componentToHex(c) {
|
||||
|
||||
/**
|
||||
* https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
||||
*
|
||||
*
|
||||
* Converts an HSL color value to RGB. Conversion formula
|
||||
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
|
||||
* Assumes h, s, and l are contained in the set [0, 1] and
|
||||
@@ -45,4 +45,4 @@ function hslToRgb(h, s, l){
|
||||
export function randomColor() {
|
||||
let rgb = hslToRgb(Math.random(), 0.6, Math.random() * 0.4 + 0.4)
|
||||
return `#${componentToHex(rgb[0])}${componentToHex(rgb[1])}${componentToHex(rgb[2])}`
|
||||
}
|
||||
}
|
||||
|
@@ -56,4 +56,4 @@ export class LocalizedDateParserFormatter extends NgbDateParserFormatter {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ export const environment = {
|
||||
apiBaseUrl: document.baseURI + "api/",
|
||||
apiVersion: "2",
|
||||
appTitle: "Paperless-ng",
|
||||
version: "1.4.4",
|
||||
version: "1.4.5",
|
||||
webSocketHost: window.location.host,
|
||||
webSocketProtocol: (window.location.protocol == "https:" ? "wss:" : "ws:"),
|
||||
webSocketBaseUrl: base_url.pathname + "ws/",
|
||||
|
@@ -3,6 +3,7 @@ import logging
|
||||
import os
|
||||
import pickle
|
||||
import re
|
||||
import shutil
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
@@ -96,7 +97,10 @@ class DocumentClassifier(object):
|
||||
raise ClassifierModelCorruptError()
|
||||
|
||||
def save(self):
|
||||
with open(settings.MODEL_FILE, "wb") as f:
|
||||
target_file = settings.MODEL_FILE
|
||||
target_file_temp = settings.MODEL_FILE + ".part"
|
||||
|
||||
with open(target_file_temp, "wb") as f:
|
||||
pickle.dump(self.FORMAT_VERSION, f)
|
||||
pickle.dump(self.data_hash, f)
|
||||
pickle.dump(self.data_vectorizer, f)
|
||||
@@ -107,6 +111,10 @@ class DocumentClassifier(object):
|
||||
pickle.dump(self.correspondent_classifier, f)
|
||||
pickle.dump(self.document_type_classifier, f)
|
||||
|
||||
if os.path.isfile(target_file):
|
||||
os.unlink(target_file)
|
||||
shutil.move(target_file_temp, target_file)
|
||||
|
||||
def train(self):
|
||||
|
||||
data = list()
|
||||
|
@@ -63,8 +63,20 @@ class Command(BaseCommand):
|
||||
action="store_true",
|
||||
help="If set, the progress bar will not be shown"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--suggest",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Return the suggestion, don't change anything."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--base-url",
|
||||
help="The base URL to use to build the link to the documents."
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
# Detect if we support color
|
||||
color = self.style.ERROR("test") != "test"
|
||||
|
||||
if options["inbox_only"]:
|
||||
queryset = Document.objects.filter(tags__is_inbox_tag=True)
|
||||
@@ -85,18 +97,27 @@ class Command(BaseCommand):
|
||||
document=document,
|
||||
classifier=classifier,
|
||||
replace=options['overwrite'],
|
||||
use_first=options['use_first'])
|
||||
use_first=options['use_first'],
|
||||
suggest=options['suggest'],
|
||||
base_url=options['base_url'],
|
||||
color=color)
|
||||
|
||||
if options['document_type']:
|
||||
set_document_type(sender=None,
|
||||
document=document,
|
||||
classifier=classifier,
|
||||
replace=options['overwrite'],
|
||||
use_first=options['use_first'])
|
||||
use_first=options['use_first'],
|
||||
suggest=options['suggest'],
|
||||
base_url=options['base_url'],
|
||||
color=color)
|
||||
|
||||
if options['tags']:
|
||||
set_tags(
|
||||
sender=None,
|
||||
document=document,
|
||||
classifier=classifier,
|
||||
replace=options['overwrite'])
|
||||
replace=options['overwrite'],
|
||||
suggest=options['suggest'],
|
||||
base_url=options['base_url'],
|
||||
color=color)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from django.utils import termcolors
|
||||
from django.conf import settings
|
||||
from django.contrib.admin.models import ADDITION, LogEntry
|
||||
from django.contrib.auth.models import User
|
||||
@@ -8,14 +9,14 @@ from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import models, DatabaseError
|
||||
from django.db.models import Q
|
||||
from django.dispatch import receiver
|
||||
from django.utils import timezone
|
||||
from django.utils import termcolors, timezone
|
||||
from filelock import FileLock
|
||||
|
||||
from .. import matching
|
||||
from ..file_handling import delete_empty_directories, \
|
||||
create_source_path_directory, \
|
||||
generate_unique_filename
|
||||
from ..models import Document, Tag
|
||||
from ..models import Document, Tag, MatchingModel
|
||||
|
||||
|
||||
logger = logging.getLogger("paperless.handlers")
|
||||
@@ -32,6 +33,9 @@ def set_correspondent(sender,
|
||||
classifier=None,
|
||||
replace=False,
|
||||
use_first=True,
|
||||
suggest=False,
|
||||
base_url=None,
|
||||
color=False,
|
||||
**kwargs):
|
||||
if document.correspondent and not replace:
|
||||
return
|
||||
@@ -60,13 +64,31 @@ def set_correspondent(sender,
|
||||
return
|
||||
|
||||
if selected or replace:
|
||||
logger.info(
|
||||
f"Assigning correspondent {selected} to {document}",
|
||||
extra={'group': logging_group}
|
||||
)
|
||||
if suggest:
|
||||
if base_url:
|
||||
print(
|
||||
termcolors.colorize(str(document), fg='green')
|
||||
if color
|
||||
else str(document)
|
||||
)
|
||||
print(f"{base_url}/documents/{document.pk}")
|
||||
else:
|
||||
print(
|
||||
(
|
||||
termcolors.colorize(str(document), fg='green')
|
||||
if color
|
||||
else str(document)
|
||||
) + f" [{document.pk}]"
|
||||
)
|
||||
print(f"Suggest correspondent {selected}")
|
||||
else:
|
||||
logger.info(
|
||||
f"Assigning correspondent {selected} to {document}",
|
||||
extra={'group': logging_group}
|
||||
)
|
||||
|
||||
document.correspondent = selected
|
||||
document.save(update_fields=("correspondent",))
|
||||
document.correspondent = selected
|
||||
document.save(update_fields=("correspondent",))
|
||||
|
||||
|
||||
def set_document_type(sender,
|
||||
@@ -75,6 +97,9 @@ def set_document_type(sender,
|
||||
classifier=None,
|
||||
replace=False,
|
||||
use_first=True,
|
||||
suggest=False,
|
||||
base_url=None,
|
||||
color=False,
|
||||
**kwargs):
|
||||
if document.document_type and not replace:
|
||||
return
|
||||
@@ -104,13 +129,31 @@ def set_document_type(sender,
|
||||
return
|
||||
|
||||
if selected or replace:
|
||||
logger.info(
|
||||
f"Assigning document type {selected} to {document}",
|
||||
extra={'group': logging_group}
|
||||
)
|
||||
if suggest:
|
||||
if base_url:
|
||||
print(
|
||||
termcolors.colorize(str(document), fg='green')
|
||||
if color
|
||||
else str(document)
|
||||
)
|
||||
print(f"{base_url}/documents/{document.pk}")
|
||||
else:
|
||||
print(
|
||||
(
|
||||
termcolors.colorize(str(document), fg='green')
|
||||
if color
|
||||
else str(document)
|
||||
) + f" [{document.pk}]"
|
||||
)
|
||||
print(f"Sugest document type {selected}")
|
||||
else:
|
||||
logger.info(
|
||||
f"Assigning document type {selected} to {document}",
|
||||
extra={'group': logging_group}
|
||||
)
|
||||
|
||||
document.document_type = selected
|
||||
document.save(update_fields=("document_type",))
|
||||
document.document_type = selected
|
||||
document.save(update_fields=("document_type",))
|
||||
|
||||
|
||||
def set_tags(sender,
|
||||
@@ -118,6 +161,9 @@ def set_tags(sender,
|
||||
logging_group=None,
|
||||
classifier=None,
|
||||
replace=False,
|
||||
suggest=False,
|
||||
base_url=None,
|
||||
color=False,
|
||||
**kwargs):
|
||||
|
||||
if replace:
|
||||
@@ -132,16 +178,48 @@ def set_tags(sender,
|
||||
|
||||
relevant_tags = set(matched_tags) - current_tags
|
||||
|
||||
if not relevant_tags:
|
||||
return
|
||||
if suggest:
|
||||
extra_tags = current_tags - set(matched_tags)
|
||||
extra_tags = [
|
||||
t for t in extra_tags
|
||||
if t.matching_algorithm == MatchingModel.MATCH_AUTO
|
||||
]
|
||||
if not relevant_tags and not extra_tags:
|
||||
return
|
||||
if base_url:
|
||||
print(
|
||||
termcolors.colorize(str(document), fg='green')
|
||||
if color
|
||||
else str(document)
|
||||
)
|
||||
print(f"{base_url}/documents/{document.pk}")
|
||||
else:
|
||||
print(
|
||||
(
|
||||
termcolors.colorize(str(document), fg='green')
|
||||
if color
|
||||
else str(document)
|
||||
) + f" [{document.pk}]"
|
||||
)
|
||||
if relevant_tags:
|
||||
print(
|
||||
"Suggest tags: " + ", ".join([t.name for t in relevant_tags])
|
||||
)
|
||||
if extra_tags:
|
||||
print("Extra tags: " + ", ".join([t.name for t in extra_tags]))
|
||||
else:
|
||||
if not relevant_tags:
|
||||
return
|
||||
|
||||
message = 'Tagging "{}" with "{}"'
|
||||
logger.info(
|
||||
message.format(document, ", ".join([t.name for t in relevant_tags])),
|
||||
extra={'group': logging_group}
|
||||
)
|
||||
message = 'Tagging "{}" with "{}"'
|
||||
logger.info(
|
||||
message.format(
|
||||
document, ", ".join([t.name for t in relevant_tags])
|
||||
),
|
||||
extra={'group': logging_group}
|
||||
)
|
||||
|
||||
document.tags.add(*relevant_tags)
|
||||
document.tags.add(*relevant_tags)
|
||||
|
||||
|
||||
@receiver(models.signals.post_delete, sender=Document)
|
||||
|
2
src/documents/static/bootstrap.min.css
vendored
2
src/documents/static/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -11,14 +11,17 @@ class TestRetagger(DirectoriesMixin, TestCase):
|
||||
self.d1 = Document.objects.create(checksum="A", title="A", content="first document")
|
||||
self.d2 = Document.objects.create(checksum="B", title="B", content="second document")
|
||||
self.d3 = Document.objects.create(checksum="C", title="C", content="unrelated document")
|
||||
self.d4 = Document.objects.create(checksum="D", title="D", content="auto document")
|
||||
|
||||
self.tag_first = Tag.objects.create(name="tag1", match="first", matching_algorithm=Tag.MATCH_ANY)
|
||||
self.tag_second = Tag.objects.create(name="tag2", match="second", matching_algorithm=Tag.MATCH_ANY)
|
||||
self.tag_inbox = Tag.objects.create(name="test", is_inbox_tag=True)
|
||||
self.tag_no_match = Tag.objects.create(name="test2")
|
||||
self.tag_auto = Tag.objects.create(name="tagauto", matching_algorithm=Tag.MATCH_AUTO)
|
||||
|
||||
self.d3.tags.add(self.tag_inbox)
|
||||
self.d3.tags.add(self.tag_no_match)
|
||||
self.d4.tags.add(self.tag_auto)
|
||||
|
||||
|
||||
self.correspondent_first = Correspondent.objects.create(
|
||||
@@ -32,7 +35,8 @@ class TestRetagger(DirectoriesMixin, TestCase):
|
||||
name="dt2", match="second", matching_algorithm=DocumentType.MATCH_ANY)
|
||||
|
||||
def get_updated_docs(self):
|
||||
return Document.objects.get(title="A"), Document.objects.get(title="B"), Document.objects.get(title="C")
|
||||
return Document.objects.get(title="A"), Document.objects.get(title="B"), \
|
||||
Document.objects.get(title="C"), Document.objects.get(title="D")
|
||||
|
||||
def setUp(self) -> None:
|
||||
super(TestRetagger, self).setUp()
|
||||
@@ -40,25 +44,26 @@ class TestRetagger(DirectoriesMixin, TestCase):
|
||||
|
||||
def test_add_tags(self):
|
||||
call_command('document_retagger', '--tags')
|
||||
d_first, d_second, d_unrelated = self.get_updated_docs()
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertEqual(d_first.tags.count(), 1)
|
||||
self.assertEqual(d_second.tags.count(), 1)
|
||||
self.assertEqual(d_unrelated.tags.count(), 2)
|
||||
self.assertEqual(d_auto.tags.count(), 1)
|
||||
|
||||
self.assertEqual(d_first.tags.first(), self.tag_first)
|
||||
self.assertEqual(d_second.tags.first(), self.tag_second)
|
||||
|
||||
def test_add_type(self):
|
||||
call_command('document_retagger', '--document_type')
|
||||
d_first, d_second, d_unrelated = self.get_updated_docs()
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertEqual(d_first.document_type, self.doctype_first)
|
||||
self.assertEqual(d_second.document_type, self.doctype_second)
|
||||
|
||||
def test_add_correspondent(self):
|
||||
call_command('document_retagger', '--correspondent')
|
||||
d_first, d_second, d_unrelated = self.get_updated_docs()
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertEqual(d_first.correspondent, self.correspondent_first)
|
||||
self.assertEqual(d_second.correspondent, self.correspondent_second)
|
||||
@@ -68,11 +73,55 @@ class TestRetagger(DirectoriesMixin, TestCase):
|
||||
|
||||
call_command('document_retagger', '--tags', '--overwrite')
|
||||
|
||||
d_first, d_second, d_unrelated = self.get_updated_docs()
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertIsNotNone(Tag.objects.get(id=self.tag_second.id))
|
||||
|
||||
self.assertCountEqual([tag.id for tag in d_first.tags.all()], [self.tag_first.id])
|
||||
self.assertCountEqual([tag.id for tag in d_second.tags.all()], [self.tag_second.id])
|
||||
self.assertCountEqual([tag.id for tag in d_unrelated.tags.all()], [self.tag_inbox.id, self.tag_no_match.id])
|
||||
self.assertEqual(d_auto.tags.count(), 0)
|
||||
|
||||
def test_add_tags_suggest(self):
|
||||
call_command('document_retagger', '--tags', '--suggest')
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertEqual(d_first.tags.count(), 0)
|
||||
self.assertEqual(d_second.tags.count(), 0)
|
||||
self.assertEqual(d_auto.tags.count(), 1)
|
||||
|
||||
def test_add_type_suggest(self):
|
||||
call_command('document_retagger', '--document_type', '--suggest')
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertEqual(d_first.document_type, None)
|
||||
self.assertEqual(d_second.document_type, None)
|
||||
|
||||
def test_add_correspondent_suggest(self):
|
||||
call_command('document_retagger', '--correspondent', '--suggest')
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertEqual(d_first.correspondent, None)
|
||||
self.assertEqual(d_second.correspondent, None)
|
||||
|
||||
def test_add_tags_suggest_url(self):
|
||||
call_command('document_retagger', '--tags', '--suggest', '--base-url=http://localhost')
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertEqual(d_first.tags.count(), 0)
|
||||
self.assertEqual(d_second.tags.count(), 0)
|
||||
self.assertEqual(d_auto.tags.count(), 1)
|
||||
|
||||
def test_add_type_suggest_url(self):
|
||||
call_command('document_retagger', '--document_type', '--suggest', '--base-url=http://localhost')
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertEqual(d_first.document_type, None)
|
||||
self.assertEqual(d_second.document_type, None)
|
||||
|
||||
def test_add_correspondent_suggest_url(self):
|
||||
call_command('document_retagger', '--correspondent', '--suggest', '--base-url=http://localhost')
|
||||
d_first, d_second, d_unrelated, d_auto = self.get_updated_docs()
|
||||
|
||||
self.assertEqual(d_first.correspondent, None)
|
||||
self.assertEqual(d_second.correspondent, None)
|
||||
|
@@ -3,7 +3,7 @@ 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-05-19 20:48\n"
|
||||
"PO-Revision-Date: 2021-05-22 10:12\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Dutch\n"
|
||||
"Language: nl_NL\n"
|
||||
@@ -674,7 +674,7 @@ msgstr "actie parameters"
|
||||
|
||||
#: 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 "Extra parameter voor de hierboven geselecteerde actie, bijvoorbeeld: de doelmap voor de verplaats naar map actie. Submappen moeten gescheiden worden door punten."
|
||||
msgstr "Extra parameter voor de hierboven geselecteerde actie, bijvoorbeeld: de doelmap voor de \"verplaats naar map\"-actie. Submappen moeten gescheiden worden door punten."
|
||||
|
||||
#: paperless_mail/models.py:184
|
||||
msgid "assign title from"
|
||||
|
@@ -420,6 +420,8 @@ Q_CLUSTER = {
|
||||
'name': 'paperless',
|
||||
'catch_up': False,
|
||||
'recycle': 1,
|
||||
'retry': 1800,
|
||||
'timeout': 1800,
|
||||
'workers': TASK_WORKERS,
|
||||
'redis': os.getenv("PAPERLESS_REDIS", "redis://localhost:6379")
|
||||
}
|
||||
|
@@ -1 +1 @@
|
||||
__version__ = (1, 4, 4)
|
||||
__version__ = (1, 4, 5)
|
||||
|
@@ -75,9 +75,9 @@ def get_rule_action(rule):
|
||||
|
||||
def make_criterias(rule):
|
||||
maximum_age = date.today() - timedelta(days=rule.maximum_age)
|
||||
criterias = {
|
||||
"date_gte": maximum_age
|
||||
}
|
||||
criterias = {}
|
||||
if rule.maximum_age > 0:
|
||||
criterias["date_gte"] = maximum_age
|
||||
if rule.filter_from:
|
||||
criterias["from_"] = rule.filter_from
|
||||
if rule.filter_subject:
|
||||
|
@@ -214,8 +214,12 @@ class RasterisedDocumentParser(DocumentParser):
|
||||
# This forces tesseract to use one core per page.
|
||||
os.environ['OMP_THREAD_LIMIT'] = "1"
|
||||
|
||||
text_original = self.extract_text(None, document_path)
|
||||
original_has_text = text_original and len(text_original) > 50
|
||||
if mime_type == "application/pdf":
|
||||
text_original = self.extract_text(None, document_path)
|
||||
original_has_text = text_original and len(text_original) > 50
|
||||
else:
|
||||
text_original = None
|
||||
original_has_text = False
|
||||
|
||||
if settings.OCR_MODE == "skip_noarchive" and original_has_text:
|
||||
self.log("debug",
|
||||
|
Reference in New Issue
Block a user