Skip to content

Commit

Permalink
Merge branch 'feature/subprocess-timeouts' into develop
Browse files Browse the repository at this point in the history
 [SVCS-683]
 Closes: #332
  • Loading branch information
felliott committed Oct 15, 2018
2 parents 42e5460 + 05408e9 commit 1188a91
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 41 deletions.
44 changes: 31 additions & 13 deletions mfr/extensions/jsc3d/export.py
@@ -1,13 +1,17 @@
import os
import shutil
import subprocess
from http import HTTPStatus
from subprocess import (DEVNULL,
check_call,
TimeoutExpired,
CalledProcessError)
from os.path import basename, splitext
from tempfile import NamedTemporaryFile

from mfr.core import exceptions
from mfr.core.extension import BaseExporter
from mfr.extensions.jsc3d.settings import (FREECAD_BIN,
FREECAD_CONVERT_SCRIPT)
from mfr.extensions.jsc3d.settings import (TIMEOUT,
FREECAD_BIN,
CONVERSION_SCRIPT)


class JSC3DExporter(BaseExporter):
Expand All @@ -22,16 +26,14 @@ def export(self):
temp_source_file.name = self.source_file_path + '.step'
shutil.copy2(self.source_file_path, temp_source_file.name)

subprocess.check_call([
FREECAD_BIN,
FREECAD_CONVERT_SCRIPT,
temp_source_file.name,
self.output_file_path,
# silence output from freecadcmd
], stdout=subprocess.DEVNULL)
check_call(
[FREECAD_BIN, CONVERSION_SCRIPT, temp_source_file.name, self.output_file_path],
stdout=DEVNULL, # silence output from freecadcmd
timeout=TIMEOUT,
)

except subprocess.CalledProcessError as err:
name, extension = os.path.splitext(os.path.split(self.source_file_path)[-1])
except CalledProcessError as err:
name, extension = splitext(basename(self.source_file_path))
raise exceptions.SubprocessError(
'Unable to export the file in the requested format, please try again later.',
process='freecad',
Expand All @@ -42,3 +44,19 @@ def export(self):
extension=extension or '',
exporter_class='jsc3d',
)

except TimeoutExpired as err:
name, extension = splitext(basename(self.source_file_path))
# The return code 52 is not the error code returned by the
# subprocess, but the error given to it by this waterbutler
# processs, for timing out.
raise exceptions.SubprocessError(
'JSC3D Conversion timed out.',
code=HTTPStatus.GATEWAY_TIMEOUT,
process='freecad',
cmd=str(err.cmd),
returncode=52,
path=str(self.source_file_path),
extension=extension or '',
exporter_class='jsc3d'
)
3 changes: 2 additions & 1 deletion mfr/extensions/jsc3d/settings.py
Expand Up @@ -3,6 +3,7 @@
config = settings.child('JSC3D_EXTENSION_CONFIG')

FREECAD_BIN = config.get('FREECAD_BIN', '/usr/bin/freecadcmd')
FREECAD_CONVERT_SCRIPT = config.get('FREECAD_CONVERT_SCRIPT', '/code/mfr/extensions/jsc3d/freecad_converter.py')
CONVERSION_SCRIPT = config.get('FREECAD_CONVERT_SCRIPT', '/code/mfr/extensions/jsc3d/freecad_converter.py')
TIMEOUT = int(config.get('FREECAD_TIMEOUT', 30)) # In seconds
EXPORT_TYPE = config.get('EXPORT_TYPE', '.stl')
EXPORT_EXCLUSIONS = config.get('EXPORT_EXCLUSIONS', '.3ds .stl .obj .ctm').split(' ')
1 change: 1 addition & 0 deletions mfr/extensions/tabular/settings.py
Expand Up @@ -37,3 +37,4 @@
})

PSPP_CONVERT_BIN = config.get('PSPP_CONVERT_BIN', '/usr/bin/pspp-convert')
PSPP_CONVERT_TIMEOUT = int(config.get('PSPP_CONVERT_TIMEOUT', 30)) # In seconds
40 changes: 29 additions & 11 deletions mfr/extensions/tabular/utilities.py
@@ -1,9 +1,14 @@
import re
import subprocess
from http import HTTPStatus
from subprocess import (check_call,
TimeoutExpired,
CalledProcessError)
from tempfile import NamedTemporaryFile

from mfr.core import exceptions
from mfr.extensions.tabular import compat, settings
from mfr.extensions.tabular import compat
from mfr.core.exceptions import SubprocessError
from mfr.extensions.tabular.settings import (PSPP_CONVERT_BIN,
PSPP_CONVERT_TIMEOUT)


def header_population(headers):
Expand Down Expand Up @@ -48,20 +53,33 @@ def sav_to_csv(fp):
"""
csv_file = NamedTemporaryFile(mode='w+b', suffix='.csv')
try:
subprocess.check_call([
settings.PSPP_CONVERT_BIN,
fp.name,
csv_file.name,
])
except subprocess.CalledProcessError as err:
raise exceptions.SubprocessError(
check_call(
[PSPP_CONVERT_BIN, fp.name, csv_file.name],
timeout=PSPP_CONVERT_TIMEOUT,
)
except CalledProcessError as err:
raise SubprocessError(
'Unable to convert the SPSS file to CSV, please try again later.',
code=500,
code=HTTPStatus.INTERNAL_SERVER_ERROR,
process='pspp',
cmd=str(err.cmd),
returncode=err.returncode,
path=fp.name,
extension='sav',
exporter_class='tabular',
)
except TimeoutExpired as err:
# The return code 52 is not the error code returned by the
# subprocess, but the error given to it by this waterbutler
# processs, for timing out.
raise SubprocessError(
'CSV Conversion timed out.',
code=HTTPStatus.GATEWAY_TIMEOUT,
process='pspp',
cmd=str(err.cmd),
returncode=52,
path=fp.name,
extension='sav',
exporter_class='tabular'
)
return csv_file
34 changes: 18 additions & 16 deletions mfr/extensions/unoconv/export.py
@@ -1,35 +1,37 @@
import os
import subprocess
from http import HTTPStatus
from os.path import basename, splitext
from subprocess import run, CalledProcessError

from mfr.core import extension
from mfr.core import exceptions
from mfr.core.extension import BaseExporter
from mfr.core.exceptions import SubprocessError
from mfr.extensions.unoconv.settings import (PORT,
ADDRESS,
UNOCONV_BIN,
UNOCONV_TIMEOUT)

from mfr.extensions.unoconv import settings


class UnoconvExporter(extension.BaseExporter):
class UnoconvExporter(BaseExporter):

def export(self):
try:
subprocess.run([
settings.UNOCONV_BIN,
run([
UNOCONV_BIN,
'-n',
'-c', 'socket,host={},port={};urp;StarOffice.ComponentContext'.format(settings.ADDRESS, settings.PORT),
'-c', 'socket,host={},port={};urp;StarOffice.ComponentContext'.format(ADDRESS, PORT),
'-f', self.format,
'-o', self.output_file_path,
'-vvv',
self.source_file_path
], check=True, timeout=settings.UNOCONV_TIMEOUT)

except subprocess.CalledProcessError as err:
name, extension = os.path.splitext(os.path.split(self.source_file_path)[-1])
raise exceptions.SubprocessError(
], check=True, timeout=UNOCONV_TIMEOUT)
except CalledProcessError as err:
name, extension = splitext(basename(self.source_file_path))
raise SubprocessError(
'Unable to export the file in the requested format, please try again later.',
process='unoconv',
cmd=str(err.cmd),
returncode=err.returncode,
path=str(self.source_file_path),
code=400,
code=HTTPStatus.BAD_REQUEST,
extension=extension or '',
exporter_class='unoconv',
)

0 comments on commit 1188a91

Please sign in to comment.