Skip to content

Commit 628f4f1

Browse files
authored
Merge pull request #298 from mpsonntag/rdfExpScript
odML to RDF export script LGTM!
2 parents 8d455d1 + a4a2c67 commit 628f4f1

File tree

4 files changed

+158
-4
lines changed

4 files changed

+158
-4
lines changed

odml/info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"VERSION": "1.4.0",
2+
"VERSION": "1.4.1",
33
"FORMAT_VERSION": "1.1",
44
"AUTHOR": "Hagen Fritsch, Jan Grewe, Christian Kellner, Achilleas Koutsou, Michael Sonntag, Lyuba Zehl",
55
"COPYRIGHT": "(c) 2011-2018, German Neuroinformatics Node",

odml/scripts/__init__.py

Whitespace-only changes.

odml/scripts/odml_to_rdf.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
"""odmlToRDF
2+
3+
odmlToRDF searches for odML files within a provided SEARCHDIR
4+
and converts them to the newest odML format version and
5+
exports all found and resulting odML files to XML formatted RDF.
6+
Original files will never be overwritten.
7+
8+
Usage: odmltordf [-r] [-o OUT] SEARCHDIR
9+
10+
Arguments:
11+
SEARCHDIR Directory to search for odML files.
12+
13+
Options:
14+
-o OUT Output directory. Must exist if specified.
15+
If not specified, output files will be
16+
written to the current directory.
17+
-r Search recursively.
18+
-h --help Show this screen.
19+
--version Show version.
20+
"""
21+
22+
import os
23+
import pathlib
24+
import sys
25+
import tempfile
26+
27+
try:
28+
from StringIO import StringIO
29+
except ImportError:
30+
from io import StringIO
31+
32+
import odml
33+
34+
from docopt import docopt
35+
from odml.tools.odmlparser import ODMLReader, ODMLWriter
36+
from odml.tools.version_converter import VersionConverter as VerConf
37+
38+
try:
39+
unicode = unicode
40+
except NameError:
41+
unicode = str
42+
43+
44+
def run_rdf_export(odml_file, export_dir):
45+
"""
46+
Convert an odML file to an XML RDF file and
47+
export it to an export directory with the
48+
same name as the original file and a '.rdf' file
49+
ending.
50+
:param odml_file: odML file to be converted to RDF.
51+
:param export_dir:
52+
"""
53+
out_name = os.path.splitext(os.path.basename(odml_file))[0]
54+
out_file = os.path.join(export_dir, "%s.rdf" % out_name)
55+
doc = ODMLReader().from_file(odml_file)
56+
ODMLWriter("RDF").write_file(doc, out_file)
57+
58+
59+
def run_conversion(file_list, output_dir, rdf_dir, report, source_format="XML"):
60+
"""
61+
Convert a list of odML files to the latest odML version if required
62+
and export all files to XML RDF files in a specified output directory.
63+
:param file_list: list of files to be exported to RDF.
64+
:param output_dir: Directory where odML files converted to
65+
the latest odML version will be saved.
66+
:param rdf_dir: Directory where exported RDF files will be saved.
67+
:param report: Reporting StringIO.
68+
:param source_format: Original file format of the odML source files.
69+
XML, JSON and YAML are supported, default is XML.
70+
"""
71+
# Exceptions are kept as broad as possible to ignore any non-odML or
72+
# invalid odML files and ensuring everything that can be will be converted.
73+
for curr_file in file_list:
74+
file_path = unicode(curr_file.absolute())
75+
report.write("[Info] Handling file '%s'\n" % file_path)
76+
# When loading the current file succeeds, it is
77+
# a recent odML format file and can be exported
78+
# to RDF right away. Otherwise it needs to be
79+
# converted to the latest odML version first.
80+
try:
81+
odml.load(file_path, source_format)
82+
report.write("[Info] RDF conversion of '%s'\n" % file_path)
83+
run_rdf_export(file_path, rdf_dir)
84+
except Exception as exc:
85+
out_name = os.path.splitext(os.path.basename(file_path))[0]
86+
outfile = os.path.join(output_dir, "%s_conv.xml" % out_name)
87+
try:
88+
VerConf(file_path).write_to_file(outfile, source_format)
89+
try:
90+
report.write("[Info] RDF conversion of '%s'\n" % outfile)
91+
run_rdf_export(outfile, rdf_dir)
92+
except Exception as exc:
93+
report.write("[Error] converting '%s' to RDF: '%s'\n" %
94+
(file_path, exc))
95+
except Exception as exc:
96+
# Ignore files we cannot parse or convert
97+
report.write("[Error] version converting file '%s': '%s'\n" %
98+
(file_path, exc))
99+
100+
101+
def main(args=None):
102+
"""
103+
Convenience script to automatically convert odML files
104+
within a directory (tree) to RDF. Check the cli help
105+
for details.
106+
:param args: Command line arguments
107+
"""
108+
parser = docopt(__doc__, argv=args, version="0.1.0")
109+
110+
root = parser['SEARCHDIR']
111+
if not os.path.isdir(root):
112+
print(docopt(__doc__, "-h"))
113+
exit(1)
114+
115+
# Handle all supported odML file formats.
116+
if parser['-r']:
117+
xfiles = list(pathlib.Path(root).rglob('*.odml'))
118+
xfiles.extend(list(pathlib.Path(root).rglob('*.xml')))
119+
jfiles = list(pathlib.Path(root).rglob('*.json'))
120+
yfiles = list(pathlib.Path(root).rglob('*.yaml'))
121+
else:
122+
xfiles = list(pathlib.Path(root).glob('*.odml'))
123+
xfiles.extend(list(pathlib.Path(root).glob('*.xml')))
124+
jfiles = list(pathlib.Path(root).glob('*.json'))
125+
yfiles = list(pathlib.Path(root).glob('*.yaml'))
126+
127+
out_root = os.getcwd()
128+
if parser["-o"]:
129+
if not os.path.isdir(parser["-o"]):
130+
print("[Error] Could not find output directory '%s'" % parser["-o"])
131+
exit(1)
132+
133+
out_root = parser["-o"]
134+
135+
out_dir = tempfile.mkdtemp(prefix="odmlconv_", dir=out_root)
136+
rdf_dir = tempfile.mkdtemp(prefix="odmlrdf_", dir=out_dir)
137+
138+
# Use this monkeypatch reporter until there is a way
139+
# to run the converters silently.
140+
report = StringIO()
141+
report.write("[Info] Files will be saved to '%s'\n" % out_dir)
142+
143+
run_conversion(xfiles, out_dir, rdf_dir, report)
144+
run_conversion(jfiles, out_dir, rdf_dir, report, "JSON")
145+
run_conversion(yfiles, out_dir, rdf_dir, report, "YAML")
146+
147+
print(report.getvalue())
148+
report.close()
149+
150+
151+
if __name__ == "__main__":
152+
main(sys.argv[1:])

setup.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@
2121

2222
packages = [
2323
'odml',
24-
'odml.tools'
24+
'odml.tools',
25+
'odml.scripts'
2526
]
2627

2728
with open('README.rst') as f:
2829
description_text = f.read()
2930

30-
install_req = ["lxml", "pyyaml==3.12", "rdflib"]
31+
install_req = ["lxml", "pyyaml==3.13", "rdflib", "docopt"]
3132

3233
if sys.version_info < (3, 4):
3334
install_req += ["enum34"]
@@ -45,5 +46,6 @@
4546
include_package_data=True,
4647
long_description=description_text,
4748
classifiers=CLASSIFIERS,
48-
license="BSD"
49+
license="BSD",
50+
entry_points={'console_scripts': ['odmltordf=odml.scripts.odml_to_rdf:main']}
4951
)

0 commit comments

Comments
 (0)