Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for uploading documents via REST API #1024

Merged
merged 1 commit into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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