[cli] adds ability to override reader/writer options from cli convert.
This commit is contained in:
@ -1,7 +1,10 @@
|
|||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
import bonobo
|
import bonobo
|
||||||
|
from bonobo.commands.util.arguments import parse_variable_argument
|
||||||
|
|
||||||
SHORTCUTS = {
|
SHORTCUTS = {
|
||||||
'csv': 'text/csv',
|
'csv': 'text/csv',
|
||||||
@ -23,7 +26,7 @@ READER = 'reader'
|
|||||||
WRITER = 'writer'
|
WRITER = 'writer'
|
||||||
|
|
||||||
|
|
||||||
def resolve_factory(name, filename, factory_type):
|
def resolve_factory(name, filename, factory_type, options=None):
|
||||||
"""
|
"""
|
||||||
Try to resolve which transformation factory to use for this filename. User eventually provided a name, which has
|
Try to resolve which transformation factory to use for this filename. User eventually provided a name, which has
|
||||||
priority, otherwise we try to detect it using the mimetype detection on filename.
|
priority, otherwise we try to detect it using the mimetype detection on filename.
|
||||||
@ -42,6 +45,12 @@ def resolve_factory(name, filename, factory_type):
|
|||||||
if _ext in SHORTCUTS:
|
if _ext in SHORTCUTS:
|
||||||
name = SHORTCUTS[_ext]
|
name = SHORTCUTS[_ext]
|
||||||
|
|
||||||
|
if options:
|
||||||
|
options = dict(map(parse_variable_argument, options))
|
||||||
|
|
||||||
|
else:
|
||||||
|
options = dict()
|
||||||
|
|
||||||
if not name in REGISTRY:
|
if not name in REGISTRY:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
'Could not resolve {factory_type} factory for {filename} ({name}). Try providing it explicitely using -{opt} <format>.'.
|
'Could not resolve {factory_type} factory for {filename} ({name}). Try providing it explicitely using -{opt} <format>.'.
|
||||||
@ -49,19 +58,22 @@ def resolve_factory(name, filename, factory_type):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if factory_type == READER:
|
if factory_type == READER:
|
||||||
return REGISTRY[name][0]
|
return REGISTRY[name][0], options
|
||||||
elif factory_type == WRITER:
|
elif factory_type == WRITER:
|
||||||
return REGISTRY[name][1]
|
return REGISTRY[name][1], options
|
||||||
else:
|
else:
|
||||||
raise ValueError('Invalid factory type.')
|
raise ValueError('Invalid factory type.')
|
||||||
|
|
||||||
|
|
||||||
def execute(input, output, reader=None, reader_options=None, writer=None, writer_options=None, options=None):
|
def execute(input, output, reader=None, reader_options=None, writer=None, writer_options=None, options=None):
|
||||||
reader = resolve_factory(reader, input, READER)(input)
|
reader_factory, reader_options = resolve_factory(reader, input, READER, (options or []) + (reader_options or []))
|
||||||
writer = resolve_factory(writer, output, WRITER)(output)
|
writer_factory, writer_options = resolve_factory(writer, output, WRITER, (options or []) + (writer_options or []))
|
||||||
|
|
||||||
graph = bonobo.Graph()
|
graph = bonobo.Graph()
|
||||||
graph.add_chain(reader, writer)
|
graph.add_chain(
|
||||||
|
reader_factory(input, **reader_options),
|
||||||
|
writer_factory(output, **writer_options),
|
||||||
|
)
|
||||||
|
|
||||||
return bonobo.run(
|
return bonobo.run(
|
||||||
graph, services={
|
graph, services={
|
||||||
@ -71,11 +83,37 @@ def execute(input, output, reader=None, reader_options=None, writer=None, writer
|
|||||||
|
|
||||||
|
|
||||||
def register(parser):
|
def register(parser):
|
||||||
parser.add_argument('input')
|
parser.add_argument('input', help='Input filename.')
|
||||||
parser.add_argument('output')
|
parser.add_argument('output', help='Output filename.')
|
||||||
parser.add_argument('--' + READER, '-r')
|
parser.add_argument(
|
||||||
parser.add_argument('--' + WRITER, '-w')
|
'--' + READER,
|
||||||
# parser.add_argument('--reader-option', '-ro', dest='reader_options')
|
'-r',
|
||||||
# parser.add_argument('--writer-option', '-wo', dest='writer_options')
|
help='Choose the reader factory if it cannot be detected from extension, or if detection is wrong.'
|
||||||
# parser.add_argument('--option', '-o', dest='options')
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--' + WRITER,
|
||||||
|
'-w',
|
||||||
|
help='Choose the writer factory if it cannot be detected from extension, or if detection is wrong.'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--option',
|
||||||
|
'-O',
|
||||||
|
dest='options',
|
||||||
|
action='append',
|
||||||
|
help='Add a named option to both reader and writer factories (i.e. foo="bar").'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--' + READER + '-option',
|
||||||
|
'-' + READER[0].upper(),
|
||||||
|
dest=READER + '_options',
|
||||||
|
action='append',
|
||||||
|
help='Add a named option to the reader factory.'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--' + WRITER + '-option',
|
||||||
|
'-' + WRITER[0].upper(),
|
||||||
|
dest=WRITER + '_options',
|
||||||
|
action='append',
|
||||||
|
help='Add a named option to the writer factory.'
|
||||||
|
)
|
||||||
return execute
|
return execute
|
||||||
|
|||||||
0
bonobo/commands/util/__init__.py
Normal file
0
bonobo/commands/util/__init__.py
Normal file
26
bonobo/commands/util/arguments.py
Normal file
26
bonobo/commands/util/arguments.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def parse_variable_argument(arg):
|
||||||
|
try:
|
||||||
|
key, val = arg.split('=', 1)
|
||||||
|
except ValueError:
|
||||||
|
return arg, True
|
||||||
|
|
||||||
|
try:
|
||||||
|
val = json.loads(val)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return key, val
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_variable_argument():
|
||||||
|
assert parse_variable_argument('foo=bar') == ('foo', 'bar')
|
||||||
|
assert parse_variable_argument('foo="bar"') == ('foo', 'bar')
|
||||||
|
assert parse_variable_argument('sep=";"') == ('sep', ';')
|
||||||
|
assert parse_variable_argument('foo') == ('foo', True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_parse_var()
|
||||||
@ -70,7 +70,17 @@ def _count_counter(self, context):
|
|||||||
context.send(Bag(counter._value))
|
context.send(Bag(counter._value))
|
||||||
|
|
||||||
|
|
||||||
|
def _shorten(s, w):
|
||||||
|
if w and len(s) > w:
|
||||||
|
s = s[0:w - 3] + '...'
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
class PrettyPrinter(Configurable):
|
class PrettyPrinter(Configurable):
|
||||||
|
max_width = Option(int, required=False, __doc__='''
|
||||||
|
If set, truncates the output values longer than this to this width.
|
||||||
|
''')
|
||||||
|
|
||||||
def call(self, *args, **kwargs):
|
def call(self, *args, **kwargs):
|
||||||
formater = self._format_quiet if settings.QUIET.get() else self._format_console
|
formater = self._format_quiet if settings.QUIET.get() else self._format_console
|
||||||
|
|
||||||
@ -82,7 +92,10 @@ class PrettyPrinter(Configurable):
|
|||||||
|
|
||||||
def _format_console(self, i, item, value):
|
def _format_console(self, i, item, value):
|
||||||
return ' '.join(
|
return ' '.join(
|
||||||
((' ' if i else '•'), str(item), '=', str(value).strip().replace('\n', '\n' + CLEAR_EOL), CLEAR_EOL)
|
(
|
||||||
|
(' ' if i else '•'), str(item), '=', _shorten(str(value).strip(),
|
||||||
|
self.max_width).replace('\n', '\n' + CLEAR_EOL), CLEAR_EOL
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,7 @@ class FileHandler(Configurable):
|
|||||||
eol = Option(str, default='\n') # type: str
|
eol = Option(str, default='\n') # type: str
|
||||||
mode = Option(str) # type: str
|
mode = Option(str) # type: str
|
||||||
encoding = Option(str, default='utf-8') # type: str
|
encoding = Option(str, default='utf-8') # type: str
|
||||||
|
|
||||||
fs = Service('fs') # type: str
|
fs = Service('fs') # type: str
|
||||||
|
|
||||||
@ContextProcessor
|
@ContextProcessor
|
||||||
|
|||||||
Reference in New Issue
Block a user