Skip to content

Commit b0a6669

Browse files
committed
Force LOKit to execute in a separate process to avoid crashes.
Thanks @dukeimg for the hint and initial patch.
1 parent 8b30e6e commit b0a6669

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

templated_docs/__init__.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3+
from multiprocessing import Process, Queue
34
import os.path
45
import re
56
from tempfile import NamedTemporaryFile
@@ -75,6 +76,27 @@ def find_template_file(template_name):
7576
raise TemplateDoesNotExist(template_name)
7677

7778

79+
def _convert_subprocess(filename, format, result_queue):
80+
"""
81+
Subprocess helper to convert a file via LOKit.
82+
83+
We need it until LO doesn't crash randomly after conversion, terminating
84+
the calling process as well.
85+
"""
86+
lo_path = getattr(
87+
settings,
88+
'TEMPLATED_DOCS_LIBREOFFICE_PATH',
89+
'/usr/lib/libreoffice/program/')
90+
91+
with Office(lo_path) as lo:
92+
conv_file = NamedTemporaryFile(delete=False,
93+
suffix='.%s' % format)
94+
with lo.documentLoad(filename) as doc:
95+
doc.saveAs(str(conv_file.name))
96+
os.unlink(filename)
97+
result_queue.put(conv_file.name)
98+
99+
78100
def fill_template(template_name, context, output_format='odt'):
79101
"""
80102
Fill a document with data and convert it to the requested format.
@@ -126,16 +148,10 @@ def fill_template(template_name, context, output_format='odt'):
126148
dest.close()
127149

128150
if source_extension[1:] != output_format:
129-
lo_path = getattr(
130-
settings,
131-
'TEMPLATED_DOCS_LIBREOFFICE_PATH',
132-
'/usr/lib/libreoffice/program/')
133-
with Office(lo_path) as lo:
134-
conv_file = NamedTemporaryFile(delete=False,
135-
suffix='.%s' % output_format)
136-
with lo.documentLoad(str(dest_file.name)) as doc:
137-
doc.saveAs(str(conv_file.name))
138-
os.unlink(dest_file.name)
139-
return conv_file.name
151+
results = Queue()
152+
convertor = Process(target=_convert_subprocess,
153+
args=(str(dest_file.name), output_format, results))
154+
convertor.start()
155+
return results.get()
140156
else:
141157
return dest_file.name

0 commit comments

Comments
 (0)