1 |
commit: e2456139f555f531c6a2a13d002b81725a7c389d |
2 |
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com> |
3 |
AuthorDate: Sun Jun 30 19:52:17 2013 +0000 |
4 |
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com> |
5 |
CommitDate: Sun Jun 30 19:52:17 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=e2456139 |
7 |
|
8 |
g_sorcery/metadata: XMLGenerator |
9 |
|
10 |
--- |
11 |
g_sorcery/exceptions.py | 5 ++- |
12 |
g_sorcery/metadata.py | 62 +++++++++++++++++++++++++++++++++++++ |
13 |
tests/test_metadata.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
3 files changed, 147 insertions(+), 1 deletion(-) |
15 |
|
16 |
diff --git a/g_sorcery/exceptions.py b/g_sorcery/exceptions.py |
17 |
index 857e4ea..38a80b2 100644 |
18 |
--- a/g_sorcery/exceptions.py |
19 |
+++ b/g_sorcery/exceptions.py |
20 |
@@ -29,5 +29,8 @@ class IntegrityError(DBError): |
21 |
class DBStructureError(DBError): |
22 |
pass |
23 |
|
24 |
-class FileJSONError(Exception): |
25 |
+class FileJSONError(GSorceryError): |
26 |
+ pass |
27 |
+ |
28 |
+class XMLGeneratorError(GSorceryError): |
29 |
pass |
30 |
|
31 |
diff --git a/g_sorcery/metadata.py b/g_sorcery/metadata.py |
32 |
new file mode 100644 |
33 |
index 0000000..ccc344a |
34 |
--- /dev/null |
35 |
+++ b/g_sorcery/metadata.py |
36 |
@@ -0,0 +1,62 @@ |
37 |
+#!/usr/bin/env python |
38 |
+# -*- coding: utf-8 -*- |
39 |
+ |
40 |
+""" |
41 |
+ metadata.py |
42 |
+ ~~~~~~~~~~~ |
43 |
+ |
44 |
+ metadata generation |
45 |
+ |
46 |
+ :copyright: (c) 2013 by Jauhien Piatlicki |
47 |
+ :license: GPL-2, see LICENSE for more details. |
48 |
+""" |
49 |
+ |
50 |
+from .exceptions import XMLGeneratorError |
51 |
+ |
52 |
+import xml.etree.ElementTree as ET |
53 |
+import xml.dom.minidom as minidom |
54 |
+ |
55 |
+def prettify(tree): |
56 |
+ rough_str = ET.tostring(tree, 'unicode') |
57 |
+ reparsed = minidom.parseString(rough_str) |
58 |
+ return reparsed.toprettyxml() |
59 |
+ |
60 |
+class XMLGenerator: |
61 |
+ def __init__(self, external, schema): |
62 |
+ self.external = external |
63 |
+ self.schema = schema |
64 |
+ |
65 |
+ def generate(self, values): |
66 |
+ root = ET.Element(self.external) |
67 |
+ for tag in self.schema: |
68 |
+ self.add_tag(root, tag, values) |
69 |
+ return root |
70 |
+ |
71 |
+ def add_tag(self, root, tag, values): |
72 |
+ name = tag['name'] |
73 |
+ if not name in values: |
74 |
+ if tag['required']: |
75 |
+ raise XMLGeneratorError('Required tag not found: ' + name) |
76 |
+ return |
77 |
+ value = values[name] |
78 |
+ multiple, attr = tag['multiple'] |
79 |
+ if multiple: |
80 |
+ for v in value: |
81 |
+ self.add_single_tag(root, name, tag, v, attr) |
82 |
+ else: |
83 |
+ self.add_single_tag(root, name, tag, value) |
84 |
+ |
85 |
+ def add_single_tag(self, root, name, tag, value, attr=None): |
86 |
+ child = ET.SubElement(root, name) |
87 |
+ if attr: |
88 |
+ child.set(attr, value[0]) |
89 |
+ value = value[1] |
90 |
+ subtags = tag['subtags'] |
91 |
+ if subtags: |
92 |
+ if 'text' in value: |
93 |
+ child.text = value[text] |
94 |
+ for child_tag in subtags: |
95 |
+ self.add_tag(child, child_tag, value) |
96 |
+ else: |
97 |
+ child.text = value |
98 |
+ |
99 |
|
100 |
diff --git a/tests/test_metadata.py b/tests/test_metadata.py |
101 |
new file mode 100644 |
102 |
index 0000000..91da5bc |
103 |
--- /dev/null |
104 |
+++ b/tests/test_metadata.py |
105 |
@@ -0,0 +1,81 @@ |
106 |
+#!/usr/bin/env python |
107 |
+# -*- coding: utf-8 -*- |
108 |
+ |
109 |
+""" |
110 |
+ test_metadata.py |
111 |
+ ~~~~~~~~~~~~~~~~ |
112 |
+ |
113 |
+ metadata generator test suite |
114 |
+ |
115 |
+ :copyright: (c) 2013 by Jauhien Piatlicki |
116 |
+ :license: GPL-2, see LICENSE for more details. |
117 |
+""" |
118 |
+ |
119 |
+import xml.etree.ElementTree as ET |
120 |
+ |
121 |
+import tempfile, unittest |
122 |
+ |
123 |
+from g_sorcery import exceptions, metadata |
124 |
+ |
125 |
+class TestXMLGenerator(unittest.TestCase): |
126 |
+ def setUp(self): |
127 |
+ pass |
128 |
+ |
129 |
+ def tearDown(self): |
130 |
+ pass |
131 |
+ |
132 |
+ def test_generate(self): |
133 |
+ schema = [{'name' : 'desc', |
134 |
+ 'subtags' : [], |
135 |
+ 'multiple' : (False, ""), |
136 |
+ 'required' : True}, |
137 |
+ {'name' : 'contact', |
138 |
+ 'multiple' : (False, ""), |
139 |
+ 'required' : False, |
140 |
+ 'subtags' : [ |
141 |
+ {'name' : 'email', |
142 |
+ 'subtags' : [], |
143 |
+ 'multiple' : (False, ""), |
144 |
+ 'required' : True}, |
145 |
+ |
146 |
+ {'name' : 'phone', |
147 |
+ 'subtags' : [], |
148 |
+ 'multiple' : (False, ""), |
149 |
+ 'required' : False}, |
150 |
+ ]}, |
151 |
+ {'name' : 'multiple', |
152 |
+ 'subtags' : [], |
153 |
+ 'multiple' : (True, ""), |
154 |
+ 'required' : False}, |
155 |
+ {'name' : 'flag', |
156 |
+ 'subtags' : [], |
157 |
+ 'multiple' : (True, "name"), |
158 |
+ 'required' : False}, |
159 |
+ ] |
160 |
+ xg = metadata.XMLGenerator('test_ext', schema) |
161 |
+ self.assertRaises(exceptions.XMLGeneratorError, xg.generate, {}) |
162 |
+ tree = xg.generate({'desc' : 'test xml'}) |
163 |
+ self.assertEqual(ET.tostring(tree, encoding='unicode'), |
164 |
+ '<test_ext><desc>test xml</desc></test_ext>') |
165 |
+ tree = xg.generate({'desc' : 'test xml', |
166 |
+ 'contact' : {'email' : 'test@×××××××.com', |
167 |
+ 'phone' : '00-0'}}) |
168 |
+ self.assertEqual(ET.tostring(tree, encoding='unicode'), |
169 |
+ '<test_ext><desc>test xml</desc><contact><email>test@×××××××.com\ |
170 |
+</email><phone>00-0</phone></contact></test_ext>') |
171 |
+ tree = xg.generate({'desc' : 'test xml', |
172 |
+ 'multiple' : ['test1', 'test2', 'test3']}) |
173 |
+ self.assertEqual(ET.tostring(tree, encoding='unicode'), |
174 |
+ '<test_ext><desc>test xml</desc><multiple>test1</multiple>\ |
175 |
+<multiple>test2</multiple><multiple>test3</multiple></test_ext>') |
176 |
+ tree = xg.generate({'desc' : 'test xml', |
177 |
+ 'flag' : [('flag1', 'test1'), ('flag2', 'test2')]}) |
178 |
+ self.assertEqual(ET.tostring(tree, encoding='unicode'), |
179 |
+ '<test_ext><desc>test xml</desc><flag name="flag1">test1</flag>\ |
180 |
+<flag name="flag2">test2</flag></test_ext>') |
181 |
+ |
182 |
+ |
183 |
+def suite(): |
184 |
+ suite = unittest.TestSuite() |
185 |
+ suite.addTest(TestXMLGenerator('test_generate')) |
186 |
+ return suite |