Passed
Pull Request — master (#566)
by Konstantin
01:50
created

ocrd_models.ocrd_wf_step.OcrdWfStep.parse()   C

Complexity

Conditions 9

Size

Total Lines 27
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 26
dl 0
loc 27
rs 6.6666
c 0
b 0
f 0
cc 9
nop 2
1
import json
2
from shlex import split as shlex_split, quote
3
# only in 3.8+ :(
4
# from shlex import join as shlex_join
5
from subprocess import run, PIPE
6
7
from ocrd_utils import getLogger, parse_json_string_or_file, set_json_key_value_overrides
8
9
LOG = getLogger('ocrd.wf.step')
10
11
class OcrdWfStep():
12
13
    @classmethod
14
    def parse(cls, argstr):
15
        tokens = shlex_split(argstr)
16
        executable = tokens.pop(0)
17
        if not executable.startswith('ocrd-'):
18
            executable = 'ocrd-%s' % executable
19
        input_file_grps = []
20
        output_file_grps = []
21
        parameters = {}
22
        while tokens:
23
            if tokens[0] == '-I':
24
                for grp in tokens[1].split(','):
25
                    input_file_grps.append(grp)
26
                tokens = tokens[2:]
27
            elif tokens[0] == '-O':
28
                for grp in tokens[1].split(','):
29
                    output_file_grps.append(grp)
30
                tokens = tokens[2:]
31
            elif tokens[0] == '-p':
32
                parameters = {**parameters, **parse_json_string_or_file(tokens[1])}
33
                tokens = tokens[2:]
34
            elif tokens[0] == '-P':
35
                set_json_key_value_overrides(parameters, tokens[1:3])
36
                tokens = tokens[3:]
37
            else:
38
                raise Exception("Failed parsing task description '%s' with tokens remaining: '%s'" % (argstr, tokens))
39
        return OcrdWfStep(executable, input_file_grps, output_file_grps, parameters)
40
41
    def __init__(self, executable, input_file_grps, output_file_grps, parameters):
42
        self.executable = executable
43
        self.input_file_grps = input_file_grps
44
        self.output_file_grps = output_file_grps
45
        self.parameters = parameters
46
        self._ocrd_tool_json = None
47
48
    @property
49
    def ocrd_tool_json(self):
50
        if self._ocrd_tool_json:
51
            return self._ocrd_tool_json
52
        result = run([self.executable, '--dump-json'], stdout=PIPE, check=True, universal_newlines=True)
53
        self._ocrd_tool_json = json.loads(result.stdout)
54
        return self._ocrd_tool_json
55
56
    def __str__(self):
57
        ret = [self.executable]
58
        if self.input_file_grps:
59
            ret += ['-I', ','.join(self.input_file_grps)]
60
        if self.output_file_grps:
61
            ret += ['-O', ','.join(self.output_file_grps)]
62
        for k in self.parameters:
63
            ret += ['-P', k, json.dumps(self.parameters[k])]
64
        return ' '.join([quote(s) for s in ret])
65
66