[cli] First draft implementation of "convert" command, which builds a simple graph of reader+writer and executes it.

This commit is contained in:
Romain Dorgueil
2017-07-16 18:45:49 +02:00
parent 53d6ac5887
commit 3e961776e3
4 changed files with 65 additions and 3 deletions

View File

@ -0,0 +1,61 @@
import mimetypes
import bonobo
SHORTCUTS = {
'plain': 'text/plain',
'txt': 'text/plain',
'text': 'text/plain',
'csv': 'text/csv',
'json': 'application/json',
}
REGISTRY = {
'text/plain': (bonobo.FileReader, bonobo.FileWriter),
'text/csv': (bonobo.CsvReader, bonobo.CsvWriter),
'application/json': (bonobo.JsonReader, bonobo.JsonWriter),
}
def resolve_factory(name, filename, factory_type):
"""
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.
"""
if name is None:
name = mimetypes.guess_type(filename)[0]
if name in SHORTCUTS:
name = SHORTCUTS[name]
if not name in REGISTRY:
raise RuntimeError('Could not resolve {factory_type} factory for {filename} ({name}). Try providing it explicitely using -{opt} <format>.'.format(name=name, filename=filename, factory_type=factory_type, opt=factory_type[0]))
if factory_type == 'reader':
return REGISTRY[name][0]
elif factory_type == 'writer':
return REGISTRY[name][1]
else:
raise ValueError('Invalid factory type.')
def execute(input, output, reader=None, reader_options=None, writer=None, writer_options=None, options=None):
reader = resolve_factory(reader, input, 'reader')(input)
writer = resolve_factory(writer, output, 'writer')(output)
graph = bonobo.Graph()
graph.add_chain(reader, writer)
return bonobo.run(graph, services={
'fs': bonobo.open_fs(),
})
def register(parser):
parser.add_argument('input')
parser.add_argument('output')
parser.add_argument('--reader', '-r')
parser.add_argument('--writer', '-w')
parser.add_argument('--reader-option', '-ro', dest='reader_options')
parser.add_argument('--writer-option', '-wo', dest='writer_options')
parser.add_argument('--option', '-o', dest='options')
return execute