Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/ocrd/decorators/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from functools import partial
import sys

from ocrd_utils import (
Expand All @@ -8,6 +9,8 @@
getLogger,
parse_json_string_with_comments,
set_json_key_value_overrides,
parse_json_string_or_file,
list_resource_candidates,
)
from ocrd_validators import WorkspaceValidator
from ocrd_network import ProcessingWorker, ProcessorServer, AgentType
Expand Down Expand Up @@ -71,6 +74,18 @@ def ocrd_cli_wrap_processor(

LOG = getLogger('ocrd.cli_wrap_processor')
# LOG.info('kwargs=%s' % kwargs)
if 'parameter' in kwargs:
# Disambiguate parameter file/literal, and resolve file
disposable = processorClass(workspace=None)
# we cannot use Processor.resolve_resource() directly
# because it exits if unsuccessful
resolve = partial(list_resource_candidates,
disposable.ocrd_tool['executable'],
moduled=disposable.moduledir)
kwargs['parameter'] = parse_json_string_or_file(*list(kwargs['parameter']),
resolve_preset_file=resolve)
else:
kwargs['parameter'] = dict()
# Merge parameter overrides and parameters
if 'parameter_override' in kwargs:
set_json_key_value_overrides(kwargs['parameter'], *kwargs['parameter_override'])
Expand Down
6 changes: 4 additions & 2 deletions src/ocrd/decorators/parameter_option.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from click import option
from ocrd_utils import parse_json_string_or_file
#from ocrd_utils import parse_json_string_or_file

__all__ = ['parameter_option', 'parameter_override_option']

Expand All @@ -11,7 +11,9 @@ def _handle_param_option(ctx, param, value):
help="Parameters, either JSON string or path to JSON file",
multiple=True,
default=['{}'],
callback=_handle_param_option)
)
# now handled in ocrd_cli_wrap_processor to resolve processor preset files
# callback=_handle_param_option)

parameter_override_option = option('-P', '--parameter-override',
help="Parameter override",
Expand Down
10 changes: 8 additions & 2 deletions src/ocrd_utils/str.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Utility functions for strings, paths and URL.
"""

from os.path import exists
import re
import json
from typing import List, Union
Expand Down Expand Up @@ -159,7 +160,7 @@ def parse_json_string_with_comments(val):
jsonstr = re.sub(r'^\s*#.*$', '', val, flags=re.MULTILINE)
return json.loads(jsonstr)

def parse_json_string_or_file(*values): # pylint: disable=unused-argument
def parse_json_string_or_file(*values, resolve_preset_file=None): # pylint: disable=unused-argument
"""
Parse a string as either the path to a JSON object or a literal JSON object.

Expand All @@ -173,7 +174,12 @@ def parse_json_string_or_file(*values): # pylint: disable=unused-argument
continue
try:
try:
with open(value, 'r') as f:
path = value
if callable(resolve_preset_file):
for candidate in resolve_preset_file(value):
if exists(candidate):
path = candidate
with open(path, 'r') as f:
value_parsed = parse_json_string_with_comments(f.read())
except (FileNotFoundError, OSError):
value_parsed = parse_json_string_with_comments(value.strip())
Expand Down
32 changes: 29 additions & 3 deletions tests/processor/test_processor.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import json

from tempfile import TemporaryDirectory
from os.path import join
from pathlib import Path
from os import environ
from tests.base import CapturingTestCase as TestCase, assets, main # pylint: disable=import-error, no-name-in-module
from tests.data import DummyProcessor, DummyProcessorWithRequiredParameters, DummyProcessorWithOutput, IncompleteProcessor

from ocrd_utils import MIMETYPE_PAGE, pushd_popd, initLogging, disableLogging
from ocrd.resolver import Resolver
from ocrd.processor.base import Processor, run_processor, run_cli

from unittest import mock
import pytest

class TestProcessor(TestCase):
Expand Down Expand Up @@ -48,8 +50,8 @@ def test_with_mets_url_input_files(self):
assert [f.mimetype for f in processor.input_files] == [MIMETYPE_PAGE, MIMETYPE_PAGE]

def test_parameter(self):
with TemporaryDirectory() as tempdir:
jsonpath = join(tempdir, 'params.json')
with TemporaryDirectory():
jsonpath = Path('params.json').name
with open(jsonpath, 'w') as f:
f.write('{"baz": "quux"}')
with open(jsonpath, 'r') as f:
Expand All @@ -73,6 +75,30 @@ def test_params_missing_required(self):
with self.assertRaisesRegex(Exception, 'is a required property'):
DummyProcessorWithRequiredParameters(workspace=self.workspace)

def test_params_preset_resolve(self):
with pushd_popd(tempdir=True) as tempdir:
with mock.patch.dict(environ, {'XDG_DATA_HOME': str(tempdir)}):
path = Path(tempdir) / 'ocrd-resources' / 'ocrd-dummy'
path.mkdir(parents=True)
path = str(path / 'preset.json')
with open(path, 'w') as out:
# it would be nicer to test some existing processor which does take params
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could install the processors in tests.data (temporarily) which output the parameters they were passed. That way, we could test not only the return value but also the output.

out.write('{}')
# FIXME: we cannot directly use self.workspace, but need a temporary copy
assert 0 == run_cli("ocrd-dummy",
resolver=Resolver(),
mets_url=self.workspace.mets_target,
input_file_grp="OCR-D-IMG",
output_file_grp="DUMMY",
parameter=path)
assert 0 == run_cli("ocrd-dummy",
resolver=Resolver(),
mets_url=self.workspace.mets_target,
input_file_grp="OCR-D-IMG",
output_file_grp="DUMMY",
parameter='preset.json',
overwrite=True)

def test_params(self):
proc = Processor(workspace=self.workspace)
self.assertEqual(proc.parameter, {})
Expand Down
2 changes: 2 additions & 0 deletions tests/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from click.testing import CliRunner
from tempfile import TemporaryDirectory
from os.path import join, exists
import pytest

from tests.base import CapturingTestCase as TestCase, assets, main, copy_of_directory # pylint: disable=import-error, no-name-in-module
from tests.data import DummyProcessor
Expand Down Expand Up @@ -105,6 +106,7 @@ def test_processor_run(self):
exit_code, out, err = self.invoke_cli(cli_dummy_processor, ['-p', '{"baz": "forty-two"}', '--mets', 'mets.xml', *DEFAULT_IN_OUT])
assert not exit_code

@pytest.mark.skip(reason="now deferred to ocrd_cli_wrap_processor (to resolve preset resources)")
def test_param_merging(self):
json1 = '{"foo": 23, "bar": 100}'
json2 = '{"foo": 42}'
Expand Down