Skip to content

Commit 0a03e89

Browse files
committed
unovonv is deprecated, use unoserver (Fixes #332) (#353)
1 parent 7524167 commit 0a03e89

5 files changed

Lines changed: 107 additions & 39 deletions

File tree

documents/tasks.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -132,38 +132,43 @@ def checksum(self, document_id: int) -> int:
132132
def convert_office_to_pdf(self, document_id: int) -> int:
133133
document = Document.objects.get(pk=document_id)
134134

135-
try:
135+
if settings.DEBUG:
136136
# Check if unoserver is running
137137
ping_result = subprocess.run(
138138
["unoping"], capture_output=True, timeout=5, check=False
139139
)
140140

141141
if ping_result.returncode != 0:
142142
# Server not running, start it as a daemon
143-
# Note: --daemon causes the process to fork, so we use Popen and don't wait
144-
subprocess.Popen(
145-
["unoserver", "--daemon", "--conversion-timeout", "300"],
146-
stdout=subprocess.DEVNULL,
147-
stderr=subprocess.DEVNULL,
148-
)
143+
# Here we want to use the system unoserver, as it needs access to LibreOffice
144+
try:
145+
subprocess.Popen(
146+
[
147+
f"{os.environ['HOME']}/.local/bin/unoserver",
148+
"--daemon",
149+
"--conversion-timeout",
150+
"300",
151+
],
152+
stdout=subprocess.DEVNULL,
153+
stderr=subprocess.DEVNULL,
154+
)
155+
except FileNotFoundError as e:
156+
raise MissingBinary("unoserver") from e
149157
# Give the server time to start up and be ready
150158
time.sleep(2)
151159

152-
try:
153-
result = subprocess.run(
154-
["unoconvert", "-", "-", "--convert-to", "pdf"],
155-
input=document.original.read(),
156-
capture_output=True,
157-
check=True,
158-
)
159-
sub = result.stdout
160-
except subprocess.CalledProcessError as e:
161-
raise DocumentProcessingError(
162-
document, exc=e, message='"unoconvert" has failed: %s' % e.output[:800]
163-
) from e
164-
165-
except FileNotFoundError as e:
166-
raise MissingBinary("unoserver") from e
160+
try:
161+
result = subprocess.run(
162+
["unoconvert", "-", "-", "--convert-to", "pdf"],
163+
input=document.original.read(),
164+
capture_output=True,
165+
check=True,
166+
)
167+
sub = result.stdout
168+
except subprocess.CalledProcessError as e:
169+
raise DocumentProcessingError(
170+
document, exc=e, message='"unoconvert" has failed: %s' % e.stderr[:800]
171+
) from e
167172

168173
document.pdf.save(str(uuid.uuid4()) + ".pdf", ContentFile(sub))
169174

documents/templates/documents/viewer.html

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ <h1 class="fs-4 mb-0 d-flex align-items-center gap-1">
3636

3737
<div class="d-sm-flex gap-2 align-items-center">
3838
<div class="mt-2 d-flex gap-2 align-items-center">
39-
{% if document.state == "DONE" %}
39+
{% if document.state == "DONE" and not document.is_unconvertible %}
4040
<a class="btn btn-primary btn-sm d-inline-flex align-items-center gap-1" data-turbo="false"
4141
href="{% url 'document_pdf' document.pk %}">
4242
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
@@ -140,7 +140,14 @@ <h1 class="fs-4 mb-0 d-flex align-items-center gap-1">
140140
{% endblock header %}
141141

142142
{% block content %}
143-
{% if document.state == "DONE" %}
143+
{% if document.is_unconvertible %}
144+
<div class="alert alert-primary" role="alert">
145+
DocHub ne sait pas générer d'aperçu pour ce document.
146+
Mais tu peux le
147+
<a href="{% url 'document_original' document.pk %}">télécharger</a>
148+
et l'ouvrir directement chez toi.
149+
</div>
150+
{% elif document.state == "DONE" %}
144151
<div class="container-xl" data-controller="viewer"
145152
data-viewer-src-value="{% url 'document_pdf' document.pk %}?embed">
146153
<div data-viewer-target="sidebar">
@@ -165,20 +172,12 @@ <h1 class="fs-4 mb-0 d-flex align-items-center gap-1">
165172

166173
</div>
167174
{% elif document.state == "ERROR" %}
168-
{% if document.is_unconvertible %}
169-
<div class="alert alert-primary" role="alert">
170-
DocHub ne sait pas générer d'aperçu pour ce document.
171-
Mais tu peux le
172-
<a href="{% url 'document_original' document.pk %}">télécharger</a>
173-
et l'ouvrir directement chez toi.
174-
</div>
175-
{% else %}
176-
<div class="alert alert-primary" role="alert">
177-
Ce document n'a pas pu être traité par DocHub à cause d'une erreur.
178-
Mais tu peux <a href="{% url 'document_original' document.pk %}">télécharger
179-
la version originale </a> si tu le désires.
180-
</div>
181-
{% endif %}
175+
176+
<div class="alert alert-primary" role="alert">
177+
Ce document n'a pas pu être traité par DocHub à cause d'une erreur.
178+
Mais tu peux <a href="{% url 'document_original' document.pk %}">télécharger
179+
la version originale </a> si tu le désires.
180+
</div>
182181
{% else %}
183182
<div class="alert alert-primary" role="alert">
184183
Ce document est en cours de traitement par DocHub et il n'est donc pas encore

documents/tests/celery_test.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import logging
2+
import os
3+
import subprocess
4+
15
from django.core.files import File
26

37
import celery
@@ -8,6 +12,8 @@
812
from documents.tasks import mutool_get_pages, process_document
913
from users.models import User
1014

15+
logger = logging.getLogger(__name__)
16+
1117
pytestmark = [pytest.mark.django_db, pytest.mark.celery]
1218

1319

@@ -55,10 +61,53 @@ def test_send_duplicate():
5561
assert Document.objects.filter(id=doc.id).count() == 0
5662

5763

64+
@pytest.fixture
65+
def unoserver():
66+
# Check if unoserver is running
67+
ping_result = subprocess.run(
68+
["unoping"], capture_output=True, timeout=5, check=False
69+
)
70+
71+
if ping_result.returncode != 0:
72+
logger.debug("Unoserver is not running, starting it ourselves")
73+
sub = subprocess.Popen(
74+
[
75+
f"{os.environ['HOME']}/.local/bin/unoserver",
76+
"--daemon",
77+
"--conversion-timeout",
78+
"300",
79+
],
80+
stdout=subprocess.PIPE,
81+
stderr=subprocess.PIPE,
82+
)
83+
logger.debug("Unoserver started")
84+
85+
yield
86+
87+
logger.debug("Killing unoserver")
88+
sub.kill()
89+
90+
# Get stdout and stderr
91+
stdout, stderr = sub.communicate(timeout=5)
92+
93+
# Log them
94+
if stdout:
95+
logger.info(
96+
"unoserver stdout:\n%s", stdout.decode("utf-8", errors="replace")
97+
)
98+
if stderr:
99+
logger.error(
100+
"unoserver stderr:\n%s", stderr.decode("utf-8", errors="replace")
101+
)
102+
else:
103+
logger.debug("Unoserver is already running")
104+
yield
105+
106+
58107
# TODO : mock unoserver and provide a fake pdf instead
59108
@pytest.mark.unoserver
60109
@pytest.mark.slow
61-
def test_send_office():
110+
def test_send_office(unoserver):
62111
doc = create_doc("My office doc", ".docx")
63112

64113
with open("documents/tests/files/2pages.docx", "rb") as fd:

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dependencies = [
3737
"psycopg[binary,pool]>=3.2.6",
3838
"python-memcached>=1.62",
3939
"redis>=5.2.1",
40+
"unoserver==3.6",
4041
]
4142

4243

@@ -65,6 +66,9 @@ dev = [
6566
norecursedirs = ".venv ve ve3 static media .git node_modules"
6667
DJANGO_SETTINGS_MODULE="www.test_settings"
6768
addopts = "--reuse-db"
69+
filterwarnings = [
70+
"ignore:builtin type.*has no __module__ attribute:DeprecationWarning"
71+
]
6872
markers = """
6973
slow: marks tests as slow (deselect with '-m "not slow"')
7074
network: marks tests using the network (deselect with '-m "not network"')

uv.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)