Skip to content

Commit b65657a

Browse files
Merge pull request #20 from pitangainnovare/impl/xml-features
Implementa funcionalidade de envio de XML para validação e transformação para PDF
2 parents fd75a6a + 6ac1c76 commit b65657a

32 files changed

+1112
-170
lines changed

compose/local/django/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ RUN python -m pip install --upgrade pip setuptools wheel
4343
# Requirements are installed here to ensure they will be cached.
4444
COPY ./requirements .
4545

46+
# Create application directory to hold DOCX layouts
47+
COPY ./docx_layouts .
48+
4649
# Update pip
4750
RUN python -m pip install --upgrade pip
4851

@@ -68,12 +71,16 @@ ARG LLAMA_VERSION=0.3.14
6871

6972
WORKDIR ${APP_HOME}
7073

74+
RUN sed -i 's/main/main contrib non-free/' /etc/apt/sources.list
75+
7176
# Install required system dependencies
7277
RUN apt-get update && apt-get install --no-install-recommends -y \
7378
# psycopg2 dependencies
7479
libpq-dev \
7580
# Translations dependencies
7681
gettext \
82+
# libreoffice for document conversions
83+
default-jre libreoffice libreoffice-java-common ttf-mscorefonts-installer fonts-liberation fonts-liberation2 fonts-crosextra-carlito fonts-crosextra-caladea fonts-dejavu fonts-noto \
7784
# cleaning up unused files
7885
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
7986
&& rm -rf /var/lib/apt/lists/*

compose/production/django/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
1919
# Requirements are installed here to ensure they will be cached.
2020
COPY ./requirements .
2121

22+
# Create application directory to hold DOCX layouts
23+
COPY ./docx_layouts .
24+
2225
# Update pip
2326
RUN python -m pip install --upgrade pip
2427

@@ -47,10 +50,14 @@ WORKDIR ${APP_HOME}
4750
RUN addgroup --system django \
4851
&& adduser --system --ingroup django django
4952

53+
RUN sed -i 's/main/main contrib non-free/' /etc/apt/sources.list
54+
5055
# Install required system dependencies
5156
RUN apt-get update && apt-get install --no-install-recommends -y \
5257
# psycopg2 dependencies
5358
libpq-dev \
59+
# libreoffice for document conversions
60+
default-jre libreoffice libreoffice-java-common ttf-mscorefonts-installer fonts-liberation fonts-liberation2 fonts-crosextra-carlito fonts-crosextra-caladea fonts-dejavu fonts-noto \
5461
# Translations dependencies
5562
gettext \
5663
# cleaning up unused files

config/menu.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
WAGTAIL_MENU_APPS_ORDER = [
2+
"xml_manager",
3+
"reference",
4+
"tracker",
25
"django_celery_beat",
36
]
47

config/settings/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@
8080
"core_settings",
8181
"django_celery_beat",
8282
"tracker",
83-
"reference"
83+
"reference",
84+
"xml_manager",
8485
]
8586

8687
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS + WAGTAIL

core/utils/__init__.py

Whitespace-only changes.

core/utils/requester.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
import logging
2+
import requests
3+
4+
from tenacity import (
5+
retry,
6+
retry_if_exception_type,
7+
stop_after_attempt,
8+
wait_exponential,
9+
)
10+
11+
12+
logger = logging.getLogger(__name__)
13+
14+
15+
class RetryableError(Exception):
16+
"""Recoverable error without having to modify the data state on the client
17+
side, e.g. timeouts, errors from network partitioning, etc.
18+
"""
19+
20+
21+
class NonRetryableError(Exception):
22+
"""Recoverable error without having to modify the data state on the client
23+
side, e.g. timeouts, errors from network partitioning, etc.
24+
"""
25+
26+
27+
def _add_param(params, name, value):
28+
if value:
29+
params[name] = value
30+
return params
31+
32+
33+
@retry(
34+
retry=retry_if_exception_type(RetryableError),
35+
wait=wait_exponential(multiplier=1, min=1, max=5),
36+
stop=stop_after_attempt(5),
37+
)
38+
def post_data(
39+
url,
40+
auth=None,
41+
data=None,
42+
files=None,
43+
headers=None,
44+
json=False,
45+
timeout=2,
46+
verify=True,
47+
):
48+
"""
49+
Post data with HTTP
50+
Retry: Wait 2^x * 1 second between each retry starting with 4 seconds,
51+
then up to 10 seconds, then 10 seconds afterwards
52+
Args:
53+
url: URL address
54+
files: files
55+
headers: HTTP headers
56+
json: True|False
57+
verify: Verify the SSL.
58+
Returns:
59+
Return a requests.response object.
60+
Except:
61+
Raise a RetryableError to retry.
62+
"""
63+
try:
64+
params = dict(
65+
headers=headers,
66+
timeout=timeout,
67+
verify=verify,
68+
)
69+
params = _add_param(params, "auth", auth)
70+
params = _add_param(params, "files", files)
71+
params = _add_param(params, "data", data)
72+
response = requests.post(url, **params)
73+
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as exc:
74+
logger.error("Erro posting data (timeout=%s): %s, retry..., erro: %s" % (timeout, url, exc))
75+
raise RetryableError(exc) from exc
76+
except (
77+
requests.exceptions.InvalidSchema,
78+
requests.exceptions.MissingSchema,
79+
requests.exceptions.InvalidURL,
80+
) as exc:
81+
raise NonRetryableError(exc) from exc
82+
try:
83+
response.raise_for_status()
84+
except requests.HTTPError as exc:
85+
if response := is_http_error_json_response(json, response):
86+
return response
87+
if 400 <= exc.response.status_code < 500:
88+
raise NonRetryableError(exc) from exc
89+
elif 500 <= exc.response.status_code < 600:
90+
logger.error(
91+
"Erro fetching the content: %s, retry..., erro: %s" % (url, exc)
92+
)
93+
raise RetryableError(exc) from exc
94+
else:
95+
raise
96+
97+
return response.content if not json else response.json()
98+
99+
100+
def is_http_error_json_response(json, response):
101+
"""
102+
Algumas API, por exemplo, opac_5, retornam a mensagem de erro em formato
103+
JSON
104+
"""
105+
if not json:
106+
return
107+
108+
try:
109+
return response.json()
110+
except Exception as json_error:
111+
return
112+
113+
114+
@retry(
115+
retry=retry_if_exception_type(RetryableError),
116+
wait=wait_exponential(multiplier=1, min=1, max=5),
117+
stop=stop_after_attempt(5),
118+
)
119+
def fetch_data(url, params=None, headers=None, json=False, timeout=2, verify=True):
120+
"""
121+
Get the resource with HTTP
122+
Retry: Wait 2^x * 1 second between each retry starting with 4 seconds,
123+
then up to 10 seconds, then 10 seconds afterwards
124+
Args:
125+
url: URL address
126+
headers: HTTP headers
127+
json: True|False
128+
verify: Verify the SSL.
129+
Returns:
130+
Return a requests.response object.
131+
Except:
132+
Raise a RetryableError to retry.
133+
"""
134+
135+
try:
136+
logger.info("Fetching the URL: %s %s" % (url, params))
137+
response = requests.get(
138+
url, params=params, headers=headers, timeout=timeout, verify=verify
139+
)
140+
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as exc:
141+
logger.error("Erro fetching the content: %s, retry..., erro: %s" % (url, exc))
142+
raise RetryableError(exc) from exc
143+
except (
144+
requests.exceptions.InvalidSchema,
145+
requests.exceptions.MissingSchema,
146+
requests.exceptions.InvalidURL,
147+
) as exc:
148+
raise NonRetryableError(exc) from exc
149+
try:
150+
response.raise_for_status()
151+
except requests.HTTPError as exc:
152+
if 400 <= exc.response.status_code < 500:
153+
raise NonRetryableError(exc) from exc
154+
elif 500 <= exc.response.status_code < 600:
155+
logger.error(
156+
"Erro fetching the content: %s, retry..., erro: %s" % (url, exc)
157+
)
158+
raise RetryableError(exc) from exc
159+
else:
160+
raise
161+
162+
return response.content if not json else response.json()

docx_layouts/layout.docx

20.9 KB
Binary file not shown.

requirements/base.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,11 @@ whitenoise==6.6.0 # https://github.com/evansd/whitenoise
4141
# ------------------------------------------------------------------------------
4242
huggingface-hub==0.26.1
4343
llama-cpp-python==0.3.14
44+
45+
# Packtools
46+
# ------------------------------------------------------------------------------
47+
git+https://git@github.com/scieloorg/packtools@4.11.22#egg=packtools
48+
49+
# Langdetect
50+
# ------------------------------------------------------------------------------
51+
langdetect~=1.0.9

tracker/choices.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,21 @@
2828
(PROGRESS_STATUS_PENDING, _("Pending")),
2929
(PROGRESS_STATUS_IGNORED, _("ignored")),
3030
)
31+
32+
XML_DOCUMENT_PARSING_ERROR = "XPE"
33+
XML_DOCUMENT_VALIDATION_ERROR = "VDE"
34+
XML_DOCUMENT_CONVERSION_TO_DOCX_ERROR = "CDE"
35+
XML_DOCUMENT_CONVERSION_TO_HTML_ERROR = "CHE"
36+
XML_DOCUMENT_CONVERSION_TO_PDF_ERROR = "CPE"
37+
XML_DOCUMENT_CONVERSION_TO_TEX_ERROR = "CTE"
38+
XML_DOCUMENT_UNKNOWN_ERROR = "UNE"
39+
40+
XML_DOCUMENT_EVENT = [
41+
(XML_DOCUMENT_PARSING_ERROR, _("XML Parsing Error")),
42+
(XML_DOCUMENT_VALIDATION_ERROR, _("XML Validation Error")),
43+
(XML_DOCUMENT_CONVERSION_TO_DOCX_ERROR, _("XML Conversion to DOCX Error")),
44+
(XML_DOCUMENT_CONVERSION_TO_HTML_ERROR, _("XML Conversion to HTML Error")),
45+
(XML_DOCUMENT_CONVERSION_TO_PDF_ERROR, _("XML Conversion to PDF Error")),
46+
(XML_DOCUMENT_CONVERSION_TO_TEX_ERROR, _("XML Conversion to TEX Error")),
47+
(XML_DOCUMENT_UNKNOWN_ERROR, _("Unknown Error")),
48+
]

tracker/exceptions.py

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,6 @@
1-
class ProcEventCreateError(Exception):
1+
class GeneralEventCreateError(Exception):
22
...
33

44

5-
class UnexpectedEventCreateError(Exception):
6-
...
7-
8-
9-
class EventCreateError(Exception):
10-
...
11-
12-
13-
class EventReportCreateError(Exception):
14-
...
15-
16-
17-
class EventReportSaveFileError(Exception):
18-
...
19-
20-
21-
class EventReportCreateError(Exception):
22-
...
23-
24-
25-
class EventReportDeleteEventsError(Exception):
26-
...
5+
class XMLDocumentEventCreateError(Exception):
6+
...

0 commit comments

Comments
 (0)