Skip to content

Commit

Permalink
Add support for uploading documents via REST API
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Dondero authored and sbrunner committed Aug 14, 2023
1 parent e9d23fd commit 2e0be8c
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 15 deletions.
8 changes: 7 additions & 1 deletion config.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
- **`auto_cut`** _(object)_: The auto mask configuration, the mask is used to definitively mask the source image. Default: `{"enabled": false}`.
- **`enabled`** _(boolean)_: Enable the auto cut. Default: `true`.
- **`auto_mask`**: Refer to _[#/definitions/auto_mask](#definitions/auto_mask)_.
- **`no_remove_to_continue`** _(boolean)_: Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the pdf. Default: `false`.
- **`no_remove_to_continue`** _(boolean)_: Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the PDF. Default: `false`.
- **`deskew`** _(object)_: The deskew configuration.
- **`min_angle`** _(number)_: The minimum angle to detect the image skew [degree]. Default: `-45`.
- **`max_angle`** _(number)_: The maximum angle to detect the image skew [degree]. Default: `45`.
Expand All @@ -124,6 +124,12 @@
- **`graduation_text_font_color`** _(array)_: Default: `[0, 0, 0]`.
- **Items** _(integer)_
- **`graduation_text_margin`** _(integer)_: Default: `6`.
- **`rest_upload`** _(object)_: Upload the final PDF via Paperless REST API.
- **`enabled`** _(boolean)_: Enable the upload of the PDF via REST API. Default: `false`.
- **`api_url`** _(string, required)_: The URL address of the REST API, usually http://server.name/api.
- **`api_token`** _(string, required)_: The API token.
- **`consume_folder`** _(object)_: Send the final PDF to Paperless using the consume folder.
- **`enabled`** _(boolean)_: Enable using the consume folder. Default: `true`.
- <a id="definitions/contour"></a>**`contour`** _(object)_: The configuration used to find the contour.
- **`min_box_size`** _(number)_: The minimum box size to find the content [mm]. Default: `{"crop": 3, "empty": 10, "limit": 10}`.
- **`min_box_black`** _(number)_: The minimum black in a box on content find [%]. Default: `2`.
Expand Down
29 changes: 27 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion process.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
- **`auto_cut`** _(object)_: The auto mask configuration, the mask is used to definitively mask the source image. Default: `{"enabled": false}`.
- **`enabled`** _(boolean)_: Enable the auto cut. Default: `true`.
- **`auto_mask`**: Refer to _[#/definitions/auto_mask](#definitions/auto_mask)_.
- **`no_remove_to_continue`** _(boolean)_: Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the pdf. Default: `false`.
- **`no_remove_to_continue`** _(boolean)_: Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the PDF. Default: `false`.
- **`deskew`** _(object)_: The deskew configuration.
- **`min_angle`** _(number)_: The minimum angle to detect the image skew [degree]. Default: `-45`.
- **`max_angle`** _(number)_: The maximum angle to detect the image skew [degree]. Default: `45`.
Expand All @@ -144,3 +144,9 @@
- **`graduation_text_font_color`** _(array)_: Default: `[0, 0, 0]`.
- **Items** _(integer)_
- **`graduation_text_margin`** _(integer)_: Default: `6`.
- **`rest_upload`** _(object)_: Upload the final PDF via Paperless REST API.
- **`enabled`** _(boolean)_: Enable the upload of the PDF via REST API. Default: `false`.
- **`api_url`** _(string, required)_: The URL address of the REST API, usually http://server.name/api.
- **`api_token`** _(string, required)_: The API token.
- **`consume_folder`** _(object)_: Send the final PDF to Paperless using the consume folder.
- **`enabled`** _(boolean)_: Enable using the consume folder. Default: `true`.
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typing-extensions = { version = "4.7.1", optional = true }
Jinja2 = { version = "3.1.2", optional = true }
natsort = { version = "8.4.0", optional = true }
nbformat = { version = "5.9.2", optional = true }
requests = { version = "2.31.0", optional = true }

[tool.poetry.extras]
process = [
Expand All @@ -82,7 +83,8 @@ process = [
"typing-extensions",
"Jinja2",
"natsort",
"nbformat"
"nbformat",
"requests"
]

[tool.poetry.group.dev.dependencies]
Expand All @@ -94,6 +96,7 @@ pytest-rerunfailures = "12.0"
pyroma = "4.2"
typing-extensions = "4.7.1"
c2cwsgiutils = { version = "6.0.0.dev142", extras = ["test_images"] }
types-requests = "2.31.0.2"

[build-system]
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning", "poetry-plugin-tweak-dependencies-version"]
Expand Down
66 changes: 65 additions & 1 deletion scan_to_paperless/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from typing import TypedDict, Union

from typing_extensions import Required

APPEND_CREDIT_CARD_DEFAULT = False
""" Default value of the field path 'Arguments append_credit_card' """

Expand Down Expand Up @@ -163,13 +165,15 @@ class Arguments(TypedDict, total=False):
"""
No REMOVE_TO_CONTINUE.
Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the pdf.
Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the PDF.
default: False
"""

deskew: "_ArgumentsDeskew"
rule: "Rule"
rest_upload: "RestUpload"
consume_folder: "ConsumeFolder"


class AutoCut(TypedDict, total=False):
Expand Down Expand Up @@ -334,6 +338,10 @@ class AutoRotate(TypedDict, total=False):
""" Default value of the field path 'Arguments colors' """


CONSUME_FOLDER_ENABLED_DEFAULT = True
""" Default value of the field path 'Consume folder enabled' """


CONTOUR_KERNEL_SIZE_DEFAULT = 1.5
""" Default value of the field path 'Contour contour_kernel_size' """

Expand Down Expand Up @@ -424,6 +432,23 @@ class Configuration(TypedDict, total=False):
"""


class ConsumeFolder(TypedDict, total=False):
"""
Consume folder.
Send the final PDF to Paperless using the consume folder
"""

enabled: bool
"""
Consume folder enabled.
Enable using the consume folder
default: True
"""


class Contour(TypedDict, total=False):
"""
Contour.
Expand Down Expand Up @@ -1019,6 +1044,10 @@ class Ps2Pdf(TypedDict, total=False):
"""


REST_UPLOAD_ENABLED_DEFAULT = False
""" Default value of the field path 'REST upload enabled' """


ROTATE_EVEN_DEFAULT = False
""" Default value of the field path 'Mode rotate_even' """

Expand Down Expand Up @@ -1075,6 +1104,41 @@ class Ps2Pdf(TypedDict, total=False):
""" Default value of the field path 'Rule minor_graduation_space' """


class RestUpload(TypedDict, total=False):
"""
REST upload.
Upload the final PDF via Paperless REST API
"""

enabled: bool
"""
REST upload enabled.
Enable the upload of the PDF via REST API
default: False
"""

api_url: Required[str]
"""
REST upload API url.
The URL address of the REST API, usually http://server.name/api
Required property
"""

api_token: Required[str]
"""
REST upload API token.
The API token
Required property
"""


class Rule(TypedDict, total=False):
"""
Rule.
Expand Down
40 changes: 38 additions & 2 deletions scan_to_paperless/config_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@
"no_remove_to_continue": {
"type": "boolean",
"default": false,
"description": "Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the pdf.",
"description": "Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the PDF.",
"title": "No REMOVE_TO_CONTINUE"
},
"deskew": {
Expand Down Expand Up @@ -488,7 +488,6 @@
}
}
},

"rule": {
"type": "object",
"title": "Rule",
Expand Down Expand Up @@ -569,6 +568,43 @@
"default": 6
}
}
},
"rest_upload": {
"type": "object",
"title": "REST upload",
"description": "Upload the final PDF via Paperless REST API",
"properties": {
"enabled": {
"type": "boolean",
"default": false,
"description": "Enable the upload of the PDF via REST API",
"title": "REST upload enabled"
},
"api_url": {
"type": "string",
"description": "The URL address of the REST API, usually http://server.name/api",
"title": "REST upload API url"
},
"api_token": {
"type": "string",
"description": "The API token",
"title": "REST upload API token"
}
},
"required": ["api_url", "api_token"]
},
"consume_folder": {
"type": "object",
"title": "Consume folder",
"description": "Send the final PDF to Paperless using the consume folder",
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Enable using the consume folder",
"title": "Consume folder enabled"
}
}
}
}
},
Expand Down
32 changes: 30 additions & 2 deletions scan_to_paperless/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import nbformat
import numpy as np
import pikepdf
import requests
import ruamel.yaml.compat
from deskew import determine_skew_debug_images
from PIL import Image, ImageDraw, ImageFont
Expand Down Expand Up @@ -2374,7 +2375,34 @@ def finalize(
if progress:
call(["cp", temporary_pdf.name, os.path.join(root_folder, f"{count}-pikepdf.pdf")])
count += 1
call(["cp", temporary_pdf.name, destination])

if (
config["args"]
.setdefault("consume_folder", {})
.setdefault("enabled", schema.CONSUME_FOLDER_ENABLED_DEFAULT)
):
call(["cp", temporary_pdf.name, destination])
if (
config["args"]
.setdefault("rest_upload", cast(schema.RestUpload, {}))
.setdefault("enabled", schema.REST_UPLOAD_ENABLED_DEFAULT)
):
token = config["args"]["rest_upload"]["api_token"]
url = config["args"]["rest_upload"]["api_url"]
url = f"{url}/documents/post_document/"
headers = {"authorization": f"Token {token}"}

with open(temporary_pdf.name, "rb") as document_file:
files = {"document": document_file}
title = os.path.basename(root_folder)
data = {"title": title}
response = requests.post(url, headers=headers, data=data, files=files, timeout=120)
if not response.ok:
raise ScanToPaperlessException(
f"Failed ({response.status_code}) upload to "
f"'{url}' with token '{token}'\n{response.text}"
)
print(f"Uploaded {temporary_pdf.name} with title {title}")


def _process_code(name: str) -> None:
Expand Down Expand Up @@ -2519,7 +2547,7 @@ def _process(
trace = traceback.format_exc()

out = {"error": str(exception), "traceback": trace.split("\n")}
for attribute in ("returncode", "cmd"):
for attribute in ("returncode", "cmd", "description", "error_text"):
if hasattr(exception, attribute):
out[attribute] = getattr(exception, attribute)
for attribute in ("output", "stdout", "stderr"):
Expand Down
39 changes: 38 additions & 1 deletion scan_to_paperless/process_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@
"no_remove_to_continue": {
"type": "boolean",
"default": false,
"description": "Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the pdf.",
"description": "Don't wait for the deletion of the REMOVE_TO_CONTINUE file before exporting the PDF.",
"title": "No REMOVE_TO_CONTINUE"
},
"deskew": {
Expand Down Expand Up @@ -610,6 +610,43 @@
"default": 6
}
}
},
"rest_upload": {
"type": "object",
"title": "REST upload",
"description": "Upload the final PDF via Paperless REST API",
"properties": {
"enabled": {
"type": "boolean",
"default": false,
"description": "Enable the upload of the PDF via REST API",
"title": "REST upload enabled"
},
"api_url": {
"type": "string",
"description": "The URL address of the REST API, usually http://server.name/api",
"title": "REST upload API url"
},
"api_token": {
"type": "string",
"description": "The API token",
"title": "REST upload API token"
}
},
"required": ["api_url", "api_token"]
},
"consume_folder": {
"type": "object",
"title": "Consume folder",
"description": "Send the final PDF to Paperless using the consume folder",
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Enable using the consume folder",
"title": "Consume folder enabled"
}
}
}
}
}
Expand Down
Loading

0 comments on commit 2e0be8c

Please sign in to comment.