Add configuration for report convert command

Closes #13292
This commit is contained in:
Cédric Krier
2024-05-31 19:35:02 +02:00
parent 01aa71bf3d
commit 71c4f6e185
4 changed files with 61 additions and 19 deletions
+1
View File
@@ -1,3 +1,4 @@
* Add configuration for report convert command
* Use process pool to run cron
* Lock only running cron record
* Add option to skip tests that require network
+24
View File
@@ -790,6 +790,30 @@ The timeout duration of the select call when listening on a channel.
Default: ``5``
.. _config-report:
report
------
.. _config-report.convert_command:
convert_command
---------------
The command to convert document between formats.
The available keywords are:
- ``%(directory)s``: the temporary working directory
- ``%(input_format)s``: the format of the file to convert
- ``%(input_extension)s``: the extension of the file to convert
- ``%(input_path)s``: the path of the file to convert
- ``%(output_format)s``: the format to which the file must be converted
- ``%(output_extension)s``: the extension for the converted file
- ``%(output_path)s``: the path where the converted file must be written
The command must write the result in ``%(output_path)s``.
.. _config-html:
html
+1
View File
@@ -97,6 +97,7 @@ class TrytonConfigParser(configparser.ConfigParser):
self.set('bus', 'long_polling_timeout', str(5 * 60))
self.set('bus', 'cache_timeout', '5')
self.set('bus', 'select_timeout', '5')
self.add_section('report')
self.add_section('html')
self.update_environ()
self.update_etc()
+35 -19
View File
@@ -6,6 +6,8 @@ import logging
import math
import operator
import os
import pathlib
import shutil
import subprocess
import tempfile
import time
@@ -31,6 +33,7 @@ except ImportError:
from genshi.filters import Translator
from genshi.template.text import TextTemplate
from trytond.config import config
from trytond.exceptions import UserError
from trytond.i18n import gettext
from trytond.pool import Pool, PoolBase
@@ -110,6 +113,13 @@ NO_BREAKING_SPACE = '\u00A0'
# round it to 100.
REPORT_NAME_MAX_LENGTH = 100
CONVERT_COMMAND = config.get(
'report', 'convert_command',
default='soffice --headless --nolockcheck --nodefault --norestore '
'--convert-to "%(output_extension)s" '
'--outdir "%(directory)s" '
'"%(input_path)s"')
class TranslateFactory:
@@ -382,42 +392,48 @@ class Report(URLMixin, PoolBase):
if input_format == output_format and output_format in MIMETYPES:
return output_format, data
dtemp = tempfile.mkdtemp(prefix='trytond_')
path = os.path.join(
dtemp, report.report_name + os.extsep + input_format)
oext = FORMAT2EXT.get(output_format, output_format)
directory = tempfile.mkdtemp(prefix='trytond_')
input_extension = FORMAT2EXT.get(input_format, input_format)
output_extension = FORMAT2EXT.get(output_format, output_format)
path = pathlib.Path(directory, report.report_name)
input_path = path.with_suffix(os.extsep + input_extension)
output_path = path.with_suffix(os.extsep + output_extension)
mode = 'w+' if isinstance(data, str) else 'wb+'
with open(path, mode) as fp:
with open(input_path, mode) as fp:
fp.write(data)
try:
cmd = ['soffice',
'--headless', '--nolockcheck', '--nodefault', '--norestore',
'--convert-to', oext, '--outdir', dtemp, path]
output = os.path.splitext(path)[0] + os.extsep + oext
cmd = CONVERT_COMMAND % {
'directory': directory,
'input_format': input_format,
'input_extension': input_extension,
'input_path': input_path,
'output_format': output_format,
'output_extension': output_extension,
'output_path': output_path,
}
for count in range(retry, -1, -1):
if count != retry:
time.sleep(0.02 * (retry - count))
try:
subprocess.check_call(cmd, timeout=timeout)
subprocess.check_call(cmd, timeout=timeout, shell=True)
except subprocess.CalledProcessError:
if count:
continue
logger.error(
"fail to convert %s to %s", report.report_name, oext,
exc_info=True)
"fail to convert %s to %s",
report.report_name, output_format, exc_info=True)
break
if os.path.exists(output):
with open(output, 'rb') as fp:
return oext, fp.read()
if os.path.exists(output_path):
with open(output_path, 'rb') as fp:
return output_extension, fp.read()
else:
logger.error(
'fail to convert %s to %s', report.report_name, oext)
'fail to convert %s to %s',
report.report_name, output_format)
return input_format, data
finally:
try:
os.remove(path)
os.remove(output)
os.rmdir(dtemp)
shutil.rmtree(directory, ignore_errors=True)
except OSError:
pass