Skip to content

Commit 0c6b514

Browse files
authored
Merge pull request #321 from fschrader1992/master
Automatically Add IDs At Verison Conversion
2 parents ed8c0fe + b754b3c commit 0c6b514

File tree

6 files changed

+193
-17
lines changed

6 files changed

+193
-17
lines changed

odml/doc.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,21 @@ def get_terminology_equivalent(self):
141141
return None
142142
term = terminology.load(self.repository)
143143
return term
144+
def pprint(self, indent=2, max_depth=1, max_length=80, current_depth=0):
145+
"""
146+
Pretty print method to visualize Document-Section trees.
147+
148+
:param indent: number of leading spaces for every child Section or Property.
149+
:param max_depth: maximum number of hierarchical levels printed from the
150+
starting Section.
151+
:param max_length: maximum number of characters printed in one line.
152+
:param current_depth: number of hierarchical levels printed from the
153+
starting Section.
154+
"""
155+
doc_str = "[{} [{}] {}, sections: {}, repository: {}]".format(self.author, self.version,
156+
self.date, len(self._sections), self.repository)
157+
print(doc_str)
158+
159+
for s in self._sections:
160+
s.pprint(current_depth=current_depth+1, max_depth=max_depth,
161+
indent=indent, max_length=max_length)

odml/dtypes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ def default_values(dtype):
6262

6363
_dtype_map = {'str': 'string', 'bool': 'boolean'}
6464

65+
special_dtypes = ["url", "person", "text"]
66+
6567

6668
def infer_dtype(value):
6769
dtype = (type(value)).__name__

odml/property.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def __init__(self, name=None, values=None, parent=None, unit=None,
8282

8383
self._values = []
8484
self.values = values
85-
if not values and (value or isinstance(value, bool)):
85+
if not values and (value or isinstance(value, bool) or isinstance(value, int)):
8686
self.values = value
8787

8888
self.parent = parent
@@ -588,8 +588,10 @@ def extend(self, obj, strict=True):
588588

589589
new_value = self._convert_value_input(obj)
590590
if len(new_value) > 0 and strict and dtypes.infer_dtype(new_value[0]) != self.dtype:
591-
raise ValueError("odml.Property.extend: "
592-
"passed value data type does not match dtype!")
591+
592+
if not (dtypes.infer_dtype(new_value[0]) == "string" and self.dtype in dtypes.special_dtypes):
593+
raise ValueError("odml.Property.extend: passed value data type found (\"%s\") "
594+
"does not match expected dtype \"%s\"!" % (dtypes.infer_dtype(new_value[0]), self._dtype))
593595

594596
if not self._validate_values(new_value):
595597
raise ValueError("odml.Property.extend: passed value(s) cannot be converted "
@@ -618,8 +620,10 @@ def append(self, obj, strict=True):
618620
raise ValueError("odml.property.append: Use extend to add a list of values!")
619621

620622
if len(new_value) > 0 and strict and dtypes.infer_dtype(new_value[0]) != self.dtype:
621-
raise ValueError("odml.Property.append: "
622-
"passed value data type does not match dtype!")
623+
624+
if not (dtypes.infer_dtype(new_value[0]) == "string" and self.dtype in dtypes.special_dtypes):
625+
raise ValueError("odml.Property.append: passed value data type found (\"%s\") "
626+
"does not match expected dtype \"%s\"!" % (dtypes.infer_dtype(new_value[0]), self._dtype))
623627

624628
if not self._validate_values(new_value):
625629
raise ValueError("odml.Property.append: passed value(s) cannot be converted "

odml/tools/version_converter.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from ..info import FORMAT_VERSION
1010
from ..terminology import Terminologies, REPOSITORY_BASE
1111

12+
import uuid
13+
1214
try:
1315
unicode = unicode
1416
except NameError:
@@ -194,6 +196,8 @@ def _convert(self, tree):
194196
if e.tag == "repository":
195197
self._handle_repository(e)
196198

199+
tree = self._check_add_ids(tree)
200+
197201
return tree
198202

199203
def _handle_include(self, element):
@@ -410,6 +414,41 @@ def _change_entity_name(tree, elem_map, name):
410414
elem_map[named_path] += 1
411415
name.text += "-" + str(elem_map[named_path])
412416

417+
def _check_add_ids(self, tree):
418+
"""
419+
Checks, whether elements (properties) possess an UUID
420+
and adds one in case of absence.
421+
:param tree: ElementTree of the doc
422+
:return: ElementTree
423+
"""
424+
root = tree.getroot()
425+
self._add_id(root)
426+
for sec in root.iter("section"):
427+
self._add_id(sec)
428+
for prop in sec.iter("property"):
429+
self._add_id(prop)
430+
431+
return tree
432+
433+
@staticmethod
434+
def _add_id(element):
435+
"""
436+
Checks, whether an element possesses an ID. If yes, make sure it has
437+
the right format. Otherwise a new UUID is created.
438+
:param element: lxml element.
439+
"""
440+
oid = element.find("id")
441+
new_id = ET.Element("id")
442+
new_id.text = str(uuid.uuid4())
443+
if oid is not None:
444+
try:
445+
if oid.text is not None:
446+
new_id.text = str(uuid.UUID(oid.text))
447+
except ValueError as e:
448+
print(e)
449+
element.remove(oid)
450+
element.append(new_id)
451+
413452
def _log(self, msg):
414453
"""
415454
Adds the passed message to the conversion_log attribute and

test/test_property.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,18 @@ def test_value(self):
103103
with self.assertRaises(ValueError):
104104
_ = Property(name="Public-Key", value='(5689; 1254; 687)', dtype='2-tuple')
105105

106+
p3 = Property('myprop', value=0, dtype=DType.int)
107+
self.assertEqual(p3.value, [0])
108+
self.assertEqual(p3.values, [0])
109+
110+
p4 = Property('myprop', value=0, dtype=DType.boolean)
111+
self.assertEqual(p4.value, [False])
112+
self.assertEqual(p4.values, [False])
113+
114+
p5 = Property('myprop', value=0)
115+
self.assertEqual(p5.value, [0])
116+
self.assertEqual(p5.values, [0])
117+
106118
def test_value_append(self):
107119
# Test append w/o Property value or dtype
108120
prop = Property(name="append")
@@ -183,6 +195,27 @@ def test_value_append(self):
183195
self.assertEqual(len(p5), 2)
184196
self.assertRaises(ValueError, p5.append, "[a, b, c]")
185197

198+
p6 = Property(name="prop", value=["A Abraham", "B Barnes", "C Clark"], dtype=DType.person)
199+
p6.append("D Dickins")
200+
self.assertEqual(len(p6), 4)
201+
self.assertRaises(ValueError, p6.append, 1)
202+
self.assertRaises(ValueError, p6.append, 1.3)
203+
self.assertRaises(ValueError, p6.append, True)
204+
205+
p7 = Property(name="prop", value=["https://en.wikipedia.org/wiki/Earth"], dtype=DType.url)
206+
p7.append("https://en.wikipedia.org/wiki/Mars")
207+
self.assertEqual(len(p7), 2)
208+
self.assertRaises(ValueError, p7.append, 1)
209+
self.assertRaises(ValueError, p7.append, 1.3)
210+
self.assertRaises(ValueError, p7.append, True)
211+
212+
p8 = Property(name="prop", value=["Earth is No. 3."], dtype=DType.text)
213+
p8.append("Mars is No. 4.")
214+
self.assertEqual(len(p8), 2)
215+
self.assertRaises(ValueError, p8.append, 1)
216+
self.assertRaises(ValueError, p8.append, 1.3)
217+
self.assertRaises(ValueError, p8.append, True)
218+
186219
def test_value_extend(self):
187220
prop = Property(name="extend")
188221

@@ -260,6 +293,27 @@ def test_value_extend(self):
260293
with self.assertRaises(ValueError):
261294
prop.extend([6, "some text"])
262295

296+
p1 = Property(name="prop", value=["A Abraham", "B Barnes", "C Clark"], dtype=DType.person)
297+
p1.extend("D Dickins")
298+
self.assertEqual(len(p1), 4)
299+
self.assertRaises(ValueError, p1.extend, 1)
300+
self.assertRaises(ValueError, p1.extend, 1.3)
301+
self.assertRaises(ValueError, p1.extend, True)
302+
303+
p2 = Property(name="prop", value=["https://en.wikipedia.org/wiki/Earth"], dtype=DType.url)
304+
p2.extend("https://en.wikipedia.org/wiki/Mars")
305+
self.assertEqual(len(p2), 2)
306+
self.assertRaises(ValueError, p2.append, 1)
307+
self.assertRaises(ValueError, p2.append, 1.3)
308+
self.assertRaises(ValueError, p2.append, True)
309+
310+
p3 = Property(name="prop", value=["Earth is No. 3."], dtype=DType.text)
311+
p3.extend("Mars is No. 4.")
312+
self.assertEqual(len(p3), 2)
313+
self.assertRaises(ValueError, p3.append, 1)
314+
self.assertRaises(ValueError, p3.append, 1.3)
315+
self.assertRaises(ValueError, p3.append, True)
316+
263317
def test_get_set_value(self):
264318
values = [1, 2, 3, 4, 5]
265319
p = Property("property", value=values)

0 commit comments

Comments
 (0)