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

ocrd_models.ocrd_wf_step   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 55
dl 0
loc 65
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A OcrdWfStep.__str__() 0 9 4
C OcrdWfStep.parse() 0 27 9
A OcrdWfStep.ocrd_tool_json() 0 7 2
A OcrdWfStep.__init__() 0 6 1
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