Merge branch 'dev' into machine-learning

This commit is contained in:
Jonas Winkler 2018-09-06 00:29:41 +02:00
commit d26f940a91
23 changed files with 263 additions and 208 deletions

View File

@ -40,7 +40,7 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
## Attribution ## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4 to remove puritanical language. The original is available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org [homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/ [version]: http://contributor-covenant.org/version/1/4/

View File

@ -4,20 +4,20 @@ verify_ssl = true
name = "pypi" name = "pypi"
[packages] [packages]
django = "<2.0,>=1.11" django = "<2.1,>=2.0"
pillow = "*" pillow = "*"
coveralls = "*" coveralls = "*"
dateparser = "*" dateparser = "*"
django-cors-headers = "*"
django-crispy-forms = "*" django-crispy-forms = "*"
django-extensions = "*" django-extensions = "*"
django-filter = "*" django-filter = "*"
django-flat-responsive = "*"
djangorestframework = "*" djangorestframework = "*"
factory-boy = "*" factory-boy = "*"
"flake8" = "*"
filemagic = "*" filemagic = "*"
fuzzywuzzy = {extras = ["speedup"], version = "==0.15.0"} fuzzywuzzy = {extras = ["speedup"], version = "==0.15.0"}
gunicorn = "*" gunicorn = "*"
inotify-simple = "*"
langdetect = "*" langdetect = "*"
pdftotext = "*" pdftotext = "*"
pyocr = "*" pyocr = "*"

219
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "70653513e6c80b7e07f8e7fbff7592f2d22749dc5b1d723a04f921242bc9a78f" "sha256": "e20c2294bcafd346ee57901df94a515a12976ed192dc37df848b39b56bdd1f4b"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": {}, "requires": {},
@ -19,29 +19,30 @@
"sha256:37228cda29411948b422fae072f57e31d3396d2ee1c9783775980ee9c9990af6", "sha256:37228cda29411948b422fae072f57e31d3396d2ee1c9783775980ee9c9990af6",
"sha256:58587dd4dc3daefad0487f6d9ae32b4542b185e1c36db6993290e7c41ca2b47c" "sha256:58587dd4dc3daefad0487f6d9ae32b4542b185e1c36db6993290e7c41ca2b47c"
], ],
"markers": "python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.2.*' and python_version != '3.1.*' and python_version != '3.3.*'", "markers": "python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.1.*'",
"version": "==1.5" "version": "==1.5"
}, },
"atomicwrites": { "atomicwrites": {
"hashes": [ "hashes": [
"sha256:240831ea22da9ab882b551b31d4225591e5e447a68c5e188db5b89ca1d487585", "sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0",
"sha256:a24da68318b08ac9c9c45029f4a10371ab5b20e4226738e150e6e7c571630ae6" "sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee"
], ],
"version": "==1.1.5" "markers": "python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.1.*'",
"version": "==1.2.1"
}, },
"attrs": { "attrs": {
"hashes": [ "hashes": [
"sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265", "sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
"sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b" "sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
], ],
"version": "==18.1.0" "version": "==18.2.0"
}, },
"certifi": { "certifi": {
"hashes": [ "hashes": [
"sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7", "sha256:376690d6f16d32f9d1fe8932551d80b23e9d393a8578c5633a2ed39a64861638",
"sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0" "sha256:456048c7e371c089d0a77a5212fb37a2c2dce1e24146e3b7e0261736aaeaa22a"
], ],
"version": "==2018.4.16" "version": "==2018.8.24"
}, },
"chardet": { "chardet": {
"hashes": [ "hashes": [
@ -54,8 +55,11 @@
"hashes": [ "hashes": [
"sha256:03481e81d558d30d230bc12999e3edffe392d244349a90f4ef9b88425fac74ba", "sha256:03481e81d558d30d230bc12999e3edffe392d244349a90f4ef9b88425fac74ba",
"sha256:0b136648de27201056c1869a6c0d4e23f464750fd9a9ba9750b8336a244429ed", "sha256:0b136648de27201056c1869a6c0d4e23f464750fd9a9ba9750b8336a244429ed",
"sha256:10a46017fef60e16694a30627319f38a2b9b52e90182dddb6e37dcdab0f4bf95",
"sha256:198626739a79b09fa0a2f06e083ffd12eb55449b5f8bfdbeed1df4910b2ca640", "sha256:198626739a79b09fa0a2f06e083ffd12eb55449b5f8bfdbeed1df4910b2ca640",
"sha256:23d341cdd4a0371820eb2b0bd6b88f5003a7438bbedb33688cd33b8eae59affd",
"sha256:28b2191e7283f4f3568962e373b47ef7f0392993bb6660d079c62bd50fe9d162", "sha256:28b2191e7283f4f3568962e373b47ef7f0392993bb6660d079c62bd50fe9d162",
"sha256:2a5b73210bad5279ddb558d9a2bfedc7f4bf6ad7f3c988641d83c40293deaec1",
"sha256:2eb564bbf7816a9d68dd3369a510be3327f1c618d2357fa6b1216994c2e3d508", "sha256:2eb564bbf7816a9d68dd3369a510be3327f1c618d2357fa6b1216994c2e3d508",
"sha256:337ded681dd2ef9ca04ef5d93cfc87e52e09db2594c296b4a0a3662cb1b41249", "sha256:337ded681dd2ef9ca04ef5d93cfc87e52e09db2594c296b4a0a3662cb1b41249",
"sha256:3a2184c6d797a125dca8367878d3b9a178b6fdd05fdc2d35d758c3006a1cd694", "sha256:3a2184c6d797a125dca8367878d3b9a178b6fdd05fdc2d35d758c3006a1cd694",
@ -81,15 +85,16 @@
"sha256:e05cb4d9aad6233d67e0541caa7e511fa4047ed7750ec2510d466e806e0255d6", "sha256:e05cb4d9aad6233d67e0541caa7e511fa4047ed7750ec2510d466e806e0255d6",
"sha256:f3f501f345f24383c0000395b26b726e46758b71393267aeae0bd36f8b3ade80" "sha256:f3f501f345f24383c0000395b26b726e46758b71393267aeae0bd36f8b3ade80"
], ],
"markers": "python_version >= '2.6' and python_version != '3.0.*' and python_version != '3.2.*' and python_version < '4' and python_version != '3.1.*'",
"version": "==4.5.1" "version": "==4.5.1"
}, },
"coveralls": { "coveralls": {
"hashes": [ "hashes": [
"sha256:32569a43c9dbc13fa8199247580a4ab182ef439f51f65bb7f8316d377a1340e8", "sha256:9dee67e78ec17b36c52b778247762851c8e19a893c9a14e921a2fc37f05fac22",
"sha256:664794748d2e5673e347ec476159a9d87f43e0d2d44950e98ed0e27b98da8346" "sha256:aec5a1f5e34224b9089664a1b62217732381c7de361b6ed1b3c394d7187b352a"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.3.0" "version": "==1.5.0"
}, },
"dateparser": { "dateparser": {
"hashes": [ "hashes": [
@ -101,11 +106,19 @@
}, },
"django": { "django": {
"hashes": [ "hashes": [
"sha256:b7f77c0d168de4c4ad30a02ae31b9dca04fb3c10472f04918d5c02b4117bba68", "sha256:0c5b65847d00845ee404bbc0b4a85686f15eb3001ffddda3db4e9baa265bf136",
"sha256:eb9271f0874f53106a2719c0c35ce67631f6cc27cf81a60c6f8c9817b35a3f6e" "sha256:68aeea369a8130259354b6ba1fa9babe0c5ee6bced505dea4afcd00f765ae38b"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.11.14" "version": "==2.0.8"
},
"django-cors-headers": {
"hashes": [
"sha256:5545009c9b233ea7e70da7dbab7cb1c12afa01279895086f98ec243d7eab46fa",
"sha256:c4c2ee97139d18541a1be7d96fe337d1694623816d83f53cb7c00da9b94acae1"
],
"index": "pypi",
"version": "==2.4.0"
}, },
"django-crispy-forms": { "django-crispy-forms": {
"hashes": [ "hashes": [
@ -117,26 +130,19 @@
}, },
"django-extensions": { "django-extensions": {
"hashes": [ "hashes": [
"sha256:3be3debf53c77ca795bdf713726c923aa3c3f895e1a42e2e31a68c1a562346a4", "sha256:1f626353a11479014bfe0d77e76d8f866ebca1bb5d595cb57b776230b9e0eb92",
"sha256:94bfac99eb262c5ac27e53eda96925e2e53fe0b331af7dde37012d07639a649c" "sha256:f21b898598a1628cb73017fb9672e2c5e624133be9764f0eb138e0abf8a62b62"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.0.7" "version": "==2.1.2"
}, },
"django-filter": { "django-filter": {
"hashes": [ "hashes": [
"sha256:ea204242ea83790e1512c9d0d8255002a652a6f4986e93cee664f28955ba0c22", "sha256:6f4e4bc1a11151178520567b50320e5c32f8edb552139d93ea3e30613b886f56",
"sha256:ec0ef1ba23ef95b1620f5d481334413700fb33f45cd76d56a63f4b0b1d76976a" "sha256:86c3925020c27d072cdae7b828aaa5d165c2032a629abbe3c3a1be1edae61c58"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.1.0" "version": "==2.0.0"
},
"django-flat-responsive": {
"hashes": [
"sha256:451caa2700c541b52fb7ce2d34d3d8dee9e980cf29f5463bc8a8c6256a1a6474"
],
"index": "pypi",
"version": "==2.0"
}, },
"djangorestframework": { "djangorestframework": {
"hashes": [ "hashes": [
@ -157,6 +163,7 @@
"sha256:a7a84d5fa07a089186a329528f127c9d73b9de57f1a1131b82bb5320ee651f6a", "sha256:a7a84d5fa07a089186a329528f127c9d73b9de57f1a1131b82bb5320ee651f6a",
"sha256:fc155a6b553c66c838d1a22dba1dc9f5f505c43285a878c6f74a79c024750b83" "sha256:fc155a6b553c66c838d1a22dba1dc9f5f505c43285a878c6f74a79c024750b83"
], ],
"markers": "python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.1.*'",
"version": "==1.5.0" "version": "==1.5.0"
}, },
"factory-boy": { "factory-boy": {
@ -169,10 +176,10 @@
}, },
"faker": { "faker": {
"hashes": [ "hashes": [
"sha256:04645d946256b835c675c1cef7c03817a164b0c4e452018fd50b212ddff08c22", "sha256:ea7cfd3aeb1544732d08bd9cfba40c5b78e3a91e17b1a0698ab81bfc5554c628",
"sha256:fe48f35aa3443bc5655b0782d3a2f594bf4882d0e2a947b80207a60494d32907" "sha256:f6d67f04abfb2b4bea7afc7fa6c18cf4c523a67956e455668be9ae42bccc21ad"
], ],
"version": "==0.8.16" "version": "==0.9.0"
}, },
"filemagic": { "filemagic": {
"hashes": [ "hashes": [
@ -181,14 +188,6 @@
"index": "pypi", "index": "pypi",
"version": "==1.6" "version": "==1.6"
}, },
"flake8": {
"hashes": [
"sha256:7253265f7abd8b313e3892944044a365e3f4ac3fcdcfb4298f55ee9ddf188ba0",
"sha256:c7841163e2b576d435799169b78703ad6ac1bbb0f199994fc05f700b2a90ea37"
],
"index": "pypi",
"version": "==3.5.0"
},
"fuzzywuzzy": { "fuzzywuzzy": {
"hashes": [ "hashes": [
"sha256:3759bc6859daa0eecef8c82b45404bdac20c23f23136cf4c18b46b426bbc418f", "sha256:3759bc6859daa0eecef8c82b45404bdac20c23f23136cf4c18b46b426bbc418f",
@ -213,6 +212,13 @@
], ],
"version": "==2.7" "version": "==2.7"
}, },
"inotify-simple": {
"hashes": [
"sha256:fc2c10dd73278a1027d0663f2db51240af5946390f363a154361406ebdddd8dd"
],
"index": "pypi",
"version": "==1.1.8"
},
"langdetect": { "langdetect": {
"hashes": [ "hashes": [
"sha256:91a170d5f0ade380db809b3ba67f08e95fe6c6c8641f96d67a51ff7e98a9bf30" "sha256:91a170d5f0ade380db809b3ba67f08e95fe6c6c8641f96d67a51ff7e98a9bf30"
@ -220,20 +226,13 @@
"index": "pypi", "index": "pypi",
"version": "==1.0.7" "version": "==1.0.7"
}, },
"mccabe": {
"hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
],
"version": "==0.6.1"
},
"more-itertools": { "more-itertools": {
"hashes": [ "hashes": [
"sha256:2b6b9893337bfd9166bee6a62c2b0c9fe7735dcf85948b387ec8cba30e85d8e8", "sha256:c187a73da93e7a8acc0001572aebc7e3c69daf7bf6881a2cea10650bd4420092",
"sha256:6703844a52d3588f951883005efcf555e49566a48afd4db4e965d69b883980d3", "sha256:c476b5d3a34e12d40130bc2f935028b5f636df8f372dc2c1c01dc19681b2039e",
"sha256:a18d870ef2ffca2b8463c0070ad17b5978056f403fb64e3f15fe62a52db21cc0" "sha256:fcbfeaea0be121980e15bc97b3817b5202ca73d0eae185b4550cbfce2a3ebb3d"
], ],
"version": "==4.2.0" "version": "==4.3.0"
}, },
"pdftotext": { "pdftotext": {
"hashes": [ "hashes": [
@ -280,49 +279,42 @@
}, },
"pluggy": { "pluggy": {
"hashes": [ "hashes": [
"sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff", "sha256:6e3836e39f4d36ae72840833db137f7b7d35105079aee6ec4a62d9f80d594dd1",
"sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c", "sha256:95eb8364a4708392bae89035f45341871286a333f749c3141c20573d2b3876e1"
"sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5"
], ],
"version": "==0.6.0" "markers": "python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.1.*'",
"version": "==0.7.1"
}, },
"py": { "py": {
"hashes": [ "hashes": [
"sha256:3fd59af7435864e1a243790d322d763925431213b6b8529c6ca71081ace3bbf7", "sha256:06a30435d058473046be836d3fc4f27167fd84c45b99704f2fb5509ef61f9af1",
"sha256:e31fb2767eb657cbde86c454f02e99cb846d3cd9d61b318525140214fdc0e98e" "sha256:50402e9d1c9005d759426988a492e0edaadb7f4e68bcddfea586bc7432d009c6"
], ],
"markers": "python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.1.*' and python_version != '3.2.*' and python_version >= '2.7'", "markers": "python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.1.*'",
"version": "==1.5.4" "version": "==1.6.0"
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766", "sha256:cbc619d09254895b0d12c2c691e237b2e91e9b2ecf5e84c26b35400f93dcfb83",
"sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9" "sha256:cbfca99bd594a10f674d0cd97a3d802a1fdef635d4361e1a2658de47ed261e3a"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.3.1" "version": "==2.4.0"
},
"pyflakes": {
"hashes": [
"sha256:08bd6a50edf8cffa9fa09a463063c425ecaaf10d1eb0335a7e8b1401aef89e6f",
"sha256:8d616a382f243dbf19b54743f280b80198be0bca3a5396f1d2e1fca6223e8805"
],
"version": "==1.6.0"
}, },
"pyocr": { "pyocr": {
"hashes": [ "hashes": [
"sha256:9ee8b5f38dd966ca531115fc5fe4715f7fa8961a9f14cd5109c2d938c17a2043" "sha256:bdc4d43bf9b63c2a9a4b2c9a1a623a0e63c8e6600eede5dbe866b31f3a5f2207"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.5.1" "version": "==0.5.2"
}, },
"pytest": { "pytest": {
"hashes": [ "hashes": [
"sha256:0453c8676c2bee6feb0434748b068d5510273a916295fd61d306c4f22fbfd752", "sha256:2d7c49e931316cc7d1638a3e5f54f5d7b4e5225972b3c9838f3584788d27f349",
"sha256:4b208614ae6d98195430ad6bde03641c78553acee7c83cec2e85d613c0cd383d" "sha256:ad0c7db7b5d4081631e0155f5c61b80ad76ce148551aaafe3a718d65a7508b18"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.6.3" "version": "==3.7.4"
}, },
"pytest-cov": { "pytest-cov": {
"hashes": [ "hashes": [
@ -334,11 +326,11 @@
}, },
"pytest-django": { "pytest-django": {
"hashes": [ "hashes": [
"sha256:088b66211c57972e7bd072ba73ccec1c3b6f6185f894b3b8eb966d2f3b7d46cb", "sha256:2d2e0a618d91c280d463e90bcbea9b4e417609157f611a79685b1c561c4c0836",
"sha256:3fea4d0a84bf3af1f1e82448b9a91b3ddb22b659d802e026ae843040da0c3220" "sha256:59683def396923b78d7e191a7086a48193f8d5db869ace79acb38f906522bc7b"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.3.2" "version": "==3.4.2"
}, },
"pytest-env": { "pytest-env": {
"hashes": [ "hashes": [
@ -363,11 +355,11 @@
}, },
"pytest-xdist": { "pytest-xdist": {
"hashes": [ "hashes": [
"sha256:be2662264b035920ba740ed6efb1c816a83c8a22253df7766d129f6a7bfdbd35", "sha256:0875deac20f6d96597036bdf63970887a6f36d28289c2f6682faf652dfea687b",
"sha256:e8f5744acc270b3e7d915bdb4d5f471670f049b6fbd163d4cbd52203b075d30f" "sha256:28e25e79698b2662b648319d3971c0f9ae0e6500f88258ccb9b153c31110ba9b"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.22.2" "version": "==1.23.0"
}, },
"python-dateutil": { "python-dateutil": {
"hashes": [ "hashes": [
@ -379,11 +371,11 @@
}, },
"python-dotenv": { "python-dotenv": {
"hashes": [ "hashes": [
"sha256:4965ed170bf51c347a89820e8050655e9c25db3837db6602e906b6d850fad85c", "sha256:122290a38ece9fe4f162dc7c95cae3357b983505830a154d3c98ef7f6c6cea77",
"sha256:509736185257111613009974e666568a1b031b028b61b500ef1ab4ee780089d5" "sha256:4a205787bc829233de2a823aa328e44fd9996fedb954989a21f1fc67c13d7a77"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.8.2" "version": "==0.9.1"
}, },
"python-gnupg": { "python-gnupg": {
"hashes": [ "hashes": [
@ -409,23 +401,23 @@
}, },
"regex": { "regex": {
"hashes": [ "hashes": [
"sha256:0f935c4b04b60bf3904bcaa11dec702a49de61caff3b09793521759f61bd7585", "sha256:22d7ef8c2df344328a8a3c61edade2ee714e5de9360911d22a9213931c769faa",
"sha256:22a561fce0691e2819f8b4957b0a6a1829ec1df503e93569a015a01c173b401c", "sha256:3a699780c6b712c67dc23207b129ccc6a7e1270233f7aadead3ea3f83c893702",
"sha256:2fc09d427dfc7f53ed1261caf357b25932409fd1be4dae3f3bc70e353a7120bb", "sha256:42f460d349baebd5faec02a0c920988fb0300b24baf898d9c139886565b66b6c",
"sha256:309f05c0a93a1410d1250f4170257d3f4092a7a4460e46ef47925db7c930b9c6", "sha256:43bf3d79940cbdf19adda838d8b26b28b47bec793cda46590b5b25703742f440",
"sha256:3e985c6980badbf97497945cd922561639e12e7f4174f735979136c0d81cc1b4", "sha256:47d6c7f0588ef33464e00023067c4e7cce68e0d6a686a73c7ee15abfdad503d4",
"sha256:5cdfe2f16d674e2e7b341c0cd0b12cc4644d2adf248ff860c0dc74494397f001", "sha256:5b879f59f25ed9b91bc8693a9a994014b431f224f492519ad0255ce6b54b83e5",
"sha256:717ed720c872a0c4458d8de81660e1e1e5c9a3f4277b782e01d5df934e50a820", "sha256:8ba0093c412900f636b0f826c597a0c3ea0e395344bc99894ddefe88b76c9c7e",
"sha256:81709bdab6fb5db389a3123f28f7198921372144fbda03b8ab8162ef9688b61c", "sha256:a4789254a1a0bd7a637036cce0b7ed72d8cc864e93f2e9cfd10ac00ae27bb7b0",
"sha256:97d286c501c2007e43003b53a997102d5ca781fd3d9228427f942779ac43b107", "sha256:b73cea07117dca888b0c3671770b501bef19aac9c45c8ffdb5bea2cca2377b0a",
"sha256:a35138a333069cf1d19ec39e1b1aaa868a474cf215303af2bb5d08b747796d9a", "sha256:d3eb59fa3e5b5438438ec97acd9dc86f077428e020b015b43987e35bea68ef4c",
"sha256:b172583f0c5f104e059a30dd6a1f9d20693031b156558590a745d6cc3192e283", "sha256:d51d232b4e2f106deaf286001f563947fee255bc5bd209a696f027e15cf0a1e7",
"sha256:b5a739fff4f0bfeba6d889820a14b359f50bcc3466afe00ce616fd5cb9093e25", "sha256:d59b03131a8e35061b47a8f186324a95eaf30d5f6ee9cc0637e7b87d29c7c9b5",
"sha256:b65b3a347a33fec024133cd21f926f6bff1fae387ff2f380b8751a8b26a6b92c", "sha256:dd705df1b47470388fc4630e4df3cbbe7677e2ab80092a1c660cae630a307b2d",
"sha256:c42af0a812c272339ac9602bf10e5d1e022e518e5936c303624b5c11803805e3", "sha256:e87fffa437a4b00afb17af785da9b01618425d6cd984c677639deb937037d8f2",
"sha256:d421ee4a55922f2ff2561cae543458f5bff089b5a94c7dfcf60b6bef5721cd0f" "sha256:ed40e0474ab5ab228a8d133759d451b31d3ccdebaff698646e54aff82c3de4f8"
], ],
"version": "==2018.6.21" "version": "==2018.8.29"
}, },
"requests": { "requests": {
"hashes": [ "hashes": [
@ -465,6 +457,7 @@
"sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf",
"sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5"
], ],
"markers": "python_version >= '2.6' and python_version != '3.3.*' and python_version < '4' and python_version != '3.1.*' and python_version != '3.2.*' and python_version != '3.0.*'",
"version": "==1.23" "version": "==1.23"
} }
}, },
@ -492,10 +485,10 @@
}, },
"certifi": { "certifi": {
"hashes": [ "hashes": [
"sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7", "sha256:376690d6f16d32f9d1fe8932551d80b23e9d393a8578c5633a2ed39a64861638",
"sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0" "sha256:456048c7e371c089d0a77a5212fb37a2c2dce1e24146e3b7e0261736aaeaa22a"
], ],
"version": "==2018.4.16" "version": "==2018.8.24"
}, },
"chardet": { "chardet": {
"hashes": [ "hashes": [
@ -535,11 +528,11 @@
}, },
"ipython": { "ipython": {
"hashes": [ "hashes": [
"sha256:a0c96853549b246991046f32d19db7140f5b1a644cc31f0dc1edc86713b7676f", "sha256:007dcd929c14631f83daff35df0147ea51d1af420da303fd078343878bd5fb62",
"sha256:eca537aa61592aca2fef4adea12af8e42f5c335004dfa80c78caf80e8b525e5c" "sha256:b0f2ef9eada4a68ef63ee10b6dde4f35c840035c50fd24265f8052c98947d5a4"
], ],
"index": "pypi", "index": "pypi",
"version": "==6.4.0" "version": "==6.5.0"
}, },
"ipython-genutils": { "ipython-genutils": {
"hashes": [ "hashes": [
@ -577,10 +570,10 @@
}, },
"parso": { "parso": {
"hashes": [ "hashes": [
"sha256:8105449d86d858e53ce3e0044ede9dd3a395b1c9716c696af8aa3787158ab806", "sha256:35704a43a3c113cce4de228ddb39aab374b8004f4f2407d070b6a2ca784ce8a2",
"sha256:d250235e52e8f9fc5a80cc2a5f804c9fefd886b2e67a2b1099cf085f403f8e33" "sha256:895c63e93b94ac1e1690f5fdd40b65f07c8171e3e53cbd7793b5b96c0e0a7f24"
], ],
"version": "==0.3.0" "version": "==0.3.1"
}, },
"pexpect": { "pexpect": {
"hashes": [ "hashes": [
@ -663,17 +656,18 @@
}, },
"sphinx": { "sphinx": {
"hashes": [ "hashes": [
"sha256:85f7e32c8ef07f4ba5aeca728e0f7717bef0789fba8458b8d9c5c294cad134f3", "sha256:a07050845cc9a2f4026a6035cc8ed795a5ce7be6528bbc82032385c10807dfe7",
"sha256:d45480a229edf70d84ca9fae3784162b1bc75ee47e480ffe04a4b7f21a95d76d" "sha256:d719de667218d763e8fd144b7fcfeefd8d434a6201f76bf9f0f0c1fa6f47fcdb"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.7.5" "version": "==1.7.8"
}, },
"sphinxcontrib-websupport": { "sphinxcontrib-websupport": {
"hashes": [ "hashes": [
"sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd", "sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd",
"sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9" "sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9"
], ],
"markers": "python_version != '3.3.*' and python_version >= '2.7' and python_version != '3.1.*' and python_version != '3.2.*' and python_version != '3.0.*'",
"version": "==1.1.0" "version": "==1.1.0"
}, },
"traitlets": { "traitlets": {
@ -688,6 +682,7 @@
"sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf",
"sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5"
], ],
"markers": "python_version >= '2.6' and python_version != '3.3.*' and python_version < '4' and python_version != '3.1.*' and python_version != '3.2.*' and python_version != '3.0.*'",
"version": "==1.23" "version": "==1.23"
}, },
"wcwidth": { "wcwidth": {

View File

@ -1,6 +1,26 @@
Changelog Changelog
######### #########
2.2.1
=====
* `Kyle Lucy`_ reported a bug quickly after the release of 2.2.0 where we broke
the ``DISABLE_LOGIN`` feature: `#392`_.
2.2.0
=====
* Thanks to `dadosch`_, `Wolfgang Mader`_, and `Tim Brooks`_ this is the first
version of Paperless that supports Django 2.0! As a result of their hard
work, you can now also run Paperless on Python 3.7 as well: `#386`_ &
`#390`_.
* `Stéphane Brunner`_ added a few lines of code that made tagging interface a lot
easier on those of us with lots of different tags: `#391`_.
* `Kilian Koeltzsch`_ noticed a bug in how we capture & automatically create
tags, so that's fixed now too: `#384`_.
2.1.0 2.1.0
===== =====
@ -451,6 +471,11 @@ bulk of the work on this big change.
.. _mcronce: https://github.com/mcronce .. _mcronce: https://github.com/mcronce
.. _Enno Lohmeier: https://github.com/elohmeier .. _Enno Lohmeier: https://github.com/elohmeier
.. _Mark McFate: https://github.com/SummittDweller .. _Mark McFate: https://github.com/SummittDweller
.. _dadosch: https://github.com/dadosch
.. _Wolfgang Mader: https://github.com/wmader
.. _Tim Brooks: https://github.com/brookst
.. _Stéphane Brunner: https://github.com/sbrunner
.. _Kilian Koeltzsch: https://github.com/kiliankoe
.. _#20: https://github.com/danielquinn/paperless/issues/20 .. _#20: https://github.com/danielquinn/paperless/issues/20
.. _#44: https://github.com/danielquinn/paperless/issues/44 .. _#44: https://github.com/danielquinn/paperless/issues/44
@ -525,6 +550,11 @@ bulk of the work on this big change.
.. _#374: https://github.com/danielquinn/paperless/pull/374 .. _#374: https://github.com/danielquinn/paperless/pull/374
.. _#375: https://github.com/danielquinn/paperless/pull/375 .. _#375: https://github.com/danielquinn/paperless/pull/375
.. _#376: https://github.com/danielquinn/paperless/pull/376 .. _#376: https://github.com/danielquinn/paperless/pull/376
.. _#384: https://github.com/danielquinn/paperless/issues/384
.. _#386: https://github.com/danielquinn/paperless/issues/386
.. _#391: https://github.com/danielquinn/paperless/pull/391
.. _#390: https://github.com/danielquinn/paperless/pull/390
.. _#392: https://github.com/danielquinn/paperless/issues/392
.. _pipenv: https://docs.pipenv.org/ .. _pipenv: https://docs.pipenv.org/
.. _a new home on Docker Hub: https://hub.docker.com/r/danielquinn/paperless/ .. _a new home on Docker Hub: https://hub.docker.com/r/danielquinn/paperless/

View File

@ -99,6 +99,11 @@ PAPERLESS_EMAIL_SECRET=""
# as is "example.com,www.example.com", but NOT " example.com" or "example.com," # as is "example.com,www.example.com", but NOT " example.com" or "example.com,"
#PAPERLESS_ALLOWED_HOSTS="example.com,www.example.com" #PAPERLESS_ALLOWED_HOSTS="example.com,www.example.com"
# If you decide to use Paperless APIs in an ajax calls, you need to add your
# servers to the allowed hosts that can do CORS calls. By default Paperless allows
# calls from localhost:8080. The same rules as above how the list should look like.
#PAPERLESS_CORS_ALLOWED_HOSTS="localhost:8080,example.com,localhost:8000"
# To host paperless under a subpath url like example.com/paperless you set # To host paperless under a subpath url like example.com/paperless you set
# this value to /paperless. No trailing slash! # this value to /paperless. No trailing slash!
# #

View File

@ -1,53 +1,52 @@
apipkg==1.4 -i https://pypi.python.org/simple
attrs==18.1.0 apipkg==1.5; python_version != '3.1.*'
certifi==2018.4.16 atomicwrites==1.2.1; python_version != '3.1.*'
attrs==18.2.0
certifi==2018.8.24
chardet==3.0.4 chardet==3.0.4
coverage==4.5.1 coverage==4.5.1; python_version != '3.1.*'
coveralls==1.3.0 coveralls==1.5.0
dateparser==0.7.0 dateparser==0.7.0
django-cors-headers==2.4.0
django-crispy-forms==1.7.2 django-crispy-forms==1.7.2
django-extensions==2.0.7 django-extensions==2.1.2
django-filter==1.1.0 django-filter==2.0.0
django-flat-responsive==2.0 django==2.0.8
django==2.0.7
djangorestframework==3.8.2 djangorestframework==3.8.2
docopt==0.6.2 docopt==0.6.2
execnet==1.5.0 execnet==1.5.0; python_version != '3.1.*'
factory-boy==2.11.1 factory-boy==2.11.1
faker==0.8.15 faker==0.9.0
filemagic==1.6 filemagic==1.6
flake8==3.5.0
fuzzywuzzy==0.15.0 fuzzywuzzy==0.15.0
gunicorn==19.8.1 gunicorn==19.9.0
idna==2.6 idna==2.7
inotify_simple==1.1.7; sys_platform == 'linux' inotify-simple==1.1.8
langdetect==1.0.7 langdetect==1.0.7
mccabe==0.6.1 more-itertools==4.3.0
more-itertools==4.1.0 pdftotext==2.1.0
pdftotext==2.0.2 pillow==5.2.0
pillow==5.1.0 pluggy==0.7.1; python_version != '3.1.*'
pluggy==0.6.0 py==1.6.0; python_version != '3.1.*'
py==1.5.3 pycodestyle==2.4.0
pycodestyle==2.3.1 pyocr==0.5.2
pyflakes==1.6.0
pyocr==0.5.1
pytest-cov==2.5.1 pytest-cov==2.5.1
pytest-django==3.2.1 pytest-django==3.4.2
pytest-env==0.6.2 pytest-env==0.6.2
pytest-forked==0.2 pytest-forked==0.2
pytest-sugar==0.9.1 pytest-sugar==0.9.1
pytest-xdist==1.22.2 pytest-xdist==1.23.0
pytest==3.5.1 pytest==3.7.4
python-dateutil==2.7.3 python-dateutil==2.7.3
python-dotenv==0.8.2 python-dotenv==0.9.1
python-gnupg==0.4.2 python-gnupg==0.4.3
python-levenshtein==0.12.0 python-levenshtein==0.12.0
pytz==2018.4 pytz==2018.5
regex==2018.2.21 regex==2018.8.29
requests==2.18.4 requests==2.19.1
six==1.11.0 six==1.11.0
scikit-learn==0.19.2 scikit-learn==0.19.2
termcolor==1.1.0 termcolor==1.1.0
text-unidecode==1.2 text-unidecode==1.2
tzlocal==1.5.1 tzlocal==1.5.1
urllib3==1.22 urllib3==1.23; python_version != '3.0.*'

View File

@ -4,8 +4,10 @@ from django.conf import settings
from django.contrib import admin, messages from django.contrib import admin, messages
from django.contrib.admin.templatetags.admin_urls import add_preserved_filters from django.contrib.admin.templatetags.admin_urls import add_preserved_filters
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.http import HttpResponseRedirect try:
from django.urls import reverse from django.core.urlresolvers import reverse
except ImportError:
from django.urls import reverse
from django.templatetags.static import static from django.templatetags.static import static
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.http import urlquote from django.utils.http import urlquote
@ -164,6 +166,8 @@ class DocumentAdmin(CommonAdmin):
"tags_", "archive_serial_number", "document_type") "tags_", "archive_serial_number", "document_type")
list_filter = ("document_type", "tags", ('correspondent', RecentCorrespondentFilter), "correspondent", FinancialYearFilter) list_filter = ("document_type", "tags", ('correspondent', RecentCorrespondentFilter), "correspondent", FinancialYearFilter)
filter_horizontal = ("tags",)
ordering = ["-created", "correspondent"] ordering = ["-created", "correspondent"]
actions = [add_tag_to_selected, remove_tag_from_selected, set_correspondent_on_selected, remove_correspondent_from_selected, set_document_type_on_selected, remove_document_type_from_selected, run_document_classifier_on_selected] actions = [add_tag_to_selected, remove_tag_from_selected, set_correspondent_on_selected, remove_correspondent_from_selected, set_document_type_on_selected, remove_document_type_from_selected, run_document_classifier_on_selected]
@ -282,16 +286,13 @@ class DocumentAdmin(CommonAdmin):
@staticmethod @staticmethod
def _html_tag(kind, inside=None, **kwargs): def _html_tag(kind, inside=None, **kwargs):
attributes = format_html_join(' ', '{}="{}"', kwargs.items())
attributes = []
for lft, rgt in kwargs.items():
attributes.append('{}="{}"'.format(lft, rgt))
if inside is not None: if inside is not None:
return "<{kind} {attributes}>{inside}</{kind}>".format( return format_html("<{kind} {attributes}>{inside}</{kind}>",
kind=kind, attributes=" ".join(attributes), inside=inside) kind=kind, attributes=attributes, inside=inside)
return "<{} {}/>".format(kind, " ".join(attributes)) return format_html("<{} {}/>", kind, attributes)
class LogAdmin(CommonAdmin): class LogAdmin(CommonAdmin):

View File

@ -1,11 +1,11 @@
from django_filters.rest_framework import CharFilter, FilterSet from django_filters.rest_framework import CharFilter, FilterSet, BooleanFilter
from .models import Correspondent, Document, Tag, DocumentType from .models import Correspondent, Document, Tag, DocumentType
class CorrespondentFilterSet(FilterSet): class CorrespondentFilterSet(FilterSet):
class Meta(object): class Meta:
model = Correspondent model = Correspondent
fields = { fields = {
"name": [ "name": [
@ -18,7 +18,7 @@ class CorrespondentFilterSet(FilterSet):
class TagFilterSet(FilterSet): class TagFilterSet(FilterSet):
class Meta(object): class Meta:
model = Tag model = Tag
fields = { fields = {
"name": [ "name": [
@ -55,14 +55,22 @@ class DocumentFilterSet(FilterSet):
) )
} }
correspondent__name = CharFilter(name="correspondent__name", **CHAR_KWARGS) correspondent__name = CharFilter(
correspondent__slug = CharFilter(name="correspondent__slug", **CHAR_KWARGS) field_name="correspondent__name", **CHAR_KWARGS)
tags__name = CharFilter(name="tags__name", **CHAR_KWARGS) correspondent__slug = CharFilter(
tags__slug = CharFilter(name="tags__slug", **CHAR_KWARGS) field_name="correspondent__slug", **CHAR_KWARGS)
document_type__name = CharFilter(name="document_type__name", **CHAR_KWARGS) tags__name = CharFilter(
document_type__slug = CharFilter(name="document_type__slug", **CHAR_KWARGS) field_name="tags__name", **CHAR_KWARGS)
tags__slug = CharFilter(
field_name="tags__slug", **CHAR_KWARGS)
tags__empty = BooleanFilter(
field_name="tags", lookup_expr="isnull", distinct=True)
document_type__name = CharFilter(
name="document_type__name", **CHAR_KWARGS)
document_type__slug = CharFilter(
name="document_type__slug", **CHAR_KWARGS)
class Meta(object): class Meta:
model = Document model = Document
fields = { fields = {
"title": [ "title": [

View File

@ -1,7 +1,5 @@
import datetime
import logging import logging
import os import os
import sys
import time import time
from django.conf import settings from django.conf import settings
@ -13,7 +11,7 @@ from ...mail import MailFetcher, MailFetcherError
try: try:
from inotify_simple import INotify, flags from inotify_simple import INotify, flags
except ImportError: except ImportError:
pass INotify = flags = None
class Command(BaseCommand): class Command(BaseCommand):
@ -62,7 +60,8 @@ class Command(BaseCommand):
parser.add_argument( parser.add_argument(
"--no-inotify", "--no-inotify",
action="store_true", action="store_true",
help="Don't use inotify, even if it's available." help="Don't use inotify, even if it's available.",
default=False
) )
def handle(self, *args, **options): def handle(self, *args, **options):
@ -71,8 +70,7 @@ class Command(BaseCommand):
directory = options["directory"] directory = options["directory"]
loop_time = options["loop_time"] loop_time = options["loop_time"]
mail_delta = options["mail_delta"] * 60 mail_delta = options["mail_delta"] * 60
use_inotify = (not options["no_inotify"] use_inotify = INotify is not None and options["no_inotify"] is False
and "inotify_simple" in sys.modules)
try: try:
self.file_consumer = Consumer(consume=directory) self.file_consumer = Consumer(consume=directory)

View File

@ -32,7 +32,6 @@ def realign_senders(apps, schema_editor):
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('documents', '0002_auto_20151226_1316'), ('documents', '0002_auto_20151226_1316'),
] ]

View File

@ -6,9 +6,7 @@ from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
atomic = False atomic = False
dependencies = [ dependencies = [
('documents', '0010_log'), ('documents', '0010_log'),
] ]

View File

@ -112,7 +112,6 @@ def move_documents_and_create_thumbnails(apps, schema_editor):
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('documents', '0011_auto_20160303_1929'), ('documents', '0011_auto_20160303_1929'),
] ]

View File

@ -128,7 +128,6 @@ def do_nothing(apps, schema_editor):
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('documents', '0013_auto_20160325_2111'), ('documents', '0013_auto_20160325_2111'),
] ]

View File

@ -15,7 +15,6 @@ def reverse_func(apps, schema_editor):
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('documents', '0018_auto_20170715_1712'), ('documents', '0018_auto_20170715_1712'),
] ]

View File

@ -11,8 +11,8 @@ def set_added_time_to_created_time(apps, schema_editor):
doc.added = doc.created doc.added = doc.created
doc.save() doc.save()
class Migration(migrations.Migration):
class Migration(migrations.Migration):
dependencies = [ dependencies = [
('documents', '0019_add_consumer_user'), ('documents', '0019_add_consumer_user'),
] ]

View File

@ -10,7 +10,10 @@ from collections import OrderedDict
from fuzzywuzzy import fuzz from fuzzywuzzy import fuzz
from django.conf import settings from django.conf import settings
from django.urls import reverse try:
from django.core.urlresolvers import reverse
except ImportError:
from django.urls import reverse
from django.db import models from django.db import models
from django.template.defaultfilters import slugify from django.template.defaultfilters import slugify
from django.utils import timezone from django.utils import timezone
@ -27,6 +30,7 @@ class MatchingModel(models.Model):
class Meta: class Meta:
abstract = True abstract = True
ordering = ("name",)
def __str__(self): def __str__(self):
return self.name return self.name
@ -359,8 +363,10 @@ class FileInfo:
def _get_tags(cls, tags): def _get_tags(cls, tags):
r = [] r = []
for t in tags.split(","): for t in tags.split(","):
r.append( r.append(Tag.objects.get_or_create(
Tag.objects.get_or_create(slug=t, defaults={"name": t})[0]) slug=t.lower(),
defaults={"name": t}
)[0])
return tuple(r) return tuple(r)
@classmethod @classmethod

View File

@ -5,7 +5,7 @@ from .models import Correspondent, Tag, Document, Log, DocumentType
class CorrespondentSerializer(serializers.HyperlinkedModelSerializer): class CorrespondentSerializer(serializers.HyperlinkedModelSerializer):
class Meta(object): class Meta:
model = Correspondent model = Correspondent
fields = ("id", "slug", "name", "automatic_classification") fields = ("id", "slug", "name", "automatic_classification")
@ -19,7 +19,7 @@ class DocumentTypeSerializer(serializers.HyperlinkedModelSerializer):
class TagSerializer(serializers.HyperlinkedModelSerializer): class TagSerializer(serializers.HyperlinkedModelSerializer):
class Meta(object): class Meta:
model = Tag model = Tag
fields = ( fields = (
"id", "slug", "name", "colour", "automatic_classification") "id", "slug", "name", "colour", "automatic_classification")
@ -48,7 +48,7 @@ class DocumentSerializer(serializers.ModelSerializer):
document_type = DocumentTypeField( document_type = DocumentTypeField(
view_name="drf:documenttype-detail", allow_null=True) view_name="drf:documenttype-detail", allow_null=True)
class Meta(object): class Meta:
model = Document model = Document
fields = ( fields = (
"id", "id",
@ -72,7 +72,7 @@ class LogSerializer(serializers.ModelSerializer):
time = serializers.DateTimeField() time = serializers.DateTimeField()
messages = serializers.CharField() messages = serializers.CharField()
class Meta(object): class Meta:
model = Log model = Log
fields = ( fields = (
"time", "time",

View File

@ -3,7 +3,7 @@ from unittest import mock
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
from ..consumer import Consumer from ..consumer import Consumer
from ..models import FileInfo from ..models import FileInfo, Tag
class TestConsumer(TestCase): class TestConsumer(TestCase):
@ -190,6 +190,20 @@ class TestAttributes(TestCase):
() ()
) )
def test_case_insensitive_tag_creation(self):
"""
Tags should be detected and created as lower case.
:return:
"""
path = "Title - Correspondent - tAg1,TAG2.pdf"
self.assertEqual(len(FileInfo.from_path(path).tags), 2)
path = "Title - Correspondent - tag1,tag2.pdf"
self.assertEqual(len(FileInfo.from_path(path).tags), 2)
self.assertEqual(Tag.objects.all().count(), 2)
class TestFieldPermutations(TestCase): class TestFieldPermutations(TestCase):

View File

@ -61,13 +61,13 @@ INSTALLED_APPS = [
"django.contrib.messages", "django.contrib.messages",
"django.contrib.staticfiles", "django.contrib.staticfiles",
"corsheaders",
"django_extensions", "django_extensions",
"documents.apps.DocumentsConfig", "documents.apps.DocumentsConfig",
"reminders.apps.RemindersConfig", "reminders.apps.RemindersConfig",
"paperless_tesseract.apps.PaperlessTesseractConfig", "paperless_tesseract.apps.PaperlessTesseractConfig",
"flat_responsive", # TODO: Remove as of Django 2.x
"django.contrib.admin", "django.contrib.admin",
"rest_framework", "rest_framework",
@ -79,11 +79,10 @@ INSTALLED_APPS = [
if os.getenv("PAPERLESS_INSTALLED_APPS"): if os.getenv("PAPERLESS_INSTALLED_APPS"):
INSTALLED_APPS += os.getenv("PAPERLESS_INSTALLED_APPS").split(",") INSTALLED_APPS += os.getenv("PAPERLESS_INSTALLED_APPS").split(",")
MIDDLEWARE = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
@ -91,6 +90,9 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
# We allow CORS from localhost:8080
CORS_ORIGIN_WHITELIST = tuple(os.getenv("PAPERLESS_CORS_ALLOWED_HOSTS", "localhost:8080").split(","))
# If auth is disabled, we just use our "bypass" authentication middleware # If auth is disabled, we just use our "bypass" authentication middleware
if bool(os.getenv("PAPERLESS_DISABLE_LOGIN", "false").lower() in ("yes", "y", "1", "t", "true")): if bool(os.getenv("PAPERLESS_DISABLE_LOGIN", "false").lower() in ("yes", "y", "1", "t", "true")):
_index = MIDDLEWARE.index("django.contrib.auth.middleware.AuthenticationMiddleware") _index = MIDDLEWARE.index("django.contrib.auth.middleware.AuthenticationMiddleware")

View File

@ -29,10 +29,11 @@ urlpatterns = [
# API # API
url( url(
r"^api/auth/", r"^api/auth/",
include('rest_framework.urls', namespace="rest_framework") include(
('rest_framework.urls', 'rest_framework'),
namespace="rest_framework")
), ),
url(r"^api/", include((router.urls, 'drf'), namespace="drf")),
url(r"^api/", include((router.urls, 'drf'))),
# File downloads # File downloads
url( url(

View File

@ -1 +1 @@
__version__ = (2, 1, 0) __version__ = (2, 2, 1)

View File

@ -33,7 +33,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_date_format_2(self): def test_date_format_2(self):
input_file = os.path.join(self.SAMPLE_FILES, "") input_file = os.path.join(self.SAMPLE_FILES, "")
@ -43,7 +43,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_date_format_3(self): def test_date_format_3(self):
input_file = os.path.join(self.SAMPLE_FILES, "") input_file = os.path.join(self.SAMPLE_FILES, "")
@ -53,7 +53,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_date_format_4(self): def test_date_format_4(self):
input_file = os.path.join(self.SAMPLE_FILES, "") input_file = os.path.join(self.SAMPLE_FILES, "")
@ -66,7 +66,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_date_format_5(self): def test_date_format_5(self):
input_file = os.path.join(self.SAMPLE_FILES, "") input_file = os.path.join(self.SAMPLE_FILES, "")
@ -80,7 +80,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_date_format_6(self): def test_date_format_6(self):
input_file = os.path.join(self.SAMPLE_FILES, "") input_file = os.path.join(self.SAMPLE_FILES, "")
@ -100,7 +100,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_date_format_7(self): def test_date_format_7(self):
input_file = os.path.join(self.SAMPLE_FILES, "") input_file = os.path.join(self.SAMPLE_FILES, "")
@ -117,7 +117,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_date_format_8(self): def test_date_format_8(self):
input_file = os.path.join(self.SAMPLE_FILES, "") input_file = os.path.join(self.SAMPLE_FILES, "")
@ -138,7 +138,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_date_format_9(self): def test_date_format_9(self):
input_file = os.path.join(self.SAMPLE_FILES, "") input_file = os.path.join(self.SAMPLE_FILES, "")
@ -153,7 +153,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_get_text_1_pdf(self): def test_get_text_1_pdf(self):
input_file = os.path.join(self.SAMPLE_FILES, "tests_date_1.pdf") input_file = os.path.join(self.SAMPLE_FILES, "tests_date_1.pdf")
@ -359,7 +359,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_get_text_8_pdf(self): def test_get_text_8_pdf(self):
input_file = os.path.join(self.SAMPLE_FILES, "tests_date_8.pdf") input_file = os.path.join(self.SAMPLE_FILES, "tests_date_8.pdf")
@ -373,7 +373,7 @@ class TestDate(TestCase):
@mock.patch( @mock.patch(
"paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH",
SAMPLE_FILES SCRATCH
) )
def test_get_text_9_pdf(self): def test_get_text_9_pdf(self):
input_file = os.path.join(self.SAMPLE_FILES, "tests_date_9.pdf") input_file = os.path.join(self.SAMPLE_FILES, "tests_date_9.pdf")

View File

@ -3,6 +3,8 @@ from django.db import models
class Reminder(models.Model): class Reminder(models.Model):
document = models.ForeignKey("documents.Document", on_delete=models.CASCADE) document = models.ForeignKey(
"documents.Document", on_delete=models.PROTECT
)
date = models.DateTimeField() date = models.DateTimeField()
note = models.TextField(blank=True) note = models.TextField(blank=True)