1 """
2 Generic serializer implementation.
3
4 Note that the order chosen for XML elements (imports, tags, medias, resources,
5 annotations, relations, views, queries, lists) is designed to limit the number
6 of forward references, which makes the work of the parser more difficult.
7 Forward references are nevetheless still possible in meta-data, tag associated to another tag, list containing another list
8 """
9
10 import base64
11 from itertools import chain
12 from xml.etree.cElementTree import Element, ElementTree, SubElement
13
14 from advene.model.consts import ADVENE_XML
15 from advene.model.serializers.unserialized import iter_unserialized_meta_prefix
16
17 NAME = "Generic Advene XML"
18
19 EXTENSION = ".bxp"
20
21 MIMETYPE = "application/x-advene-bxp"
22
24 """Return a serializer that will serialize `package` to `file_`.
25
26 `file_` is a writable file-like object. It is the responsability of the
27 caller to close it.
28
29 The returned object must implement the interface for which
30 :class:`_Serializer` is the reference implementation.
31 """
32 return _Serializer(package, file_)
33
35 """A shortcut for ``make_serializer(package, file_).serialize()``.
36
37 See also `make_serializer`.
38 """
39 return _Serializer(package, file_).serialize()
40
41
43
45 """Perform the actual serialization."""
46 namespaces = self.namespaces = {}
47 root = self.root = Element("package", xmlns=self.default_ns)
48 package = self.package
49 namespaces = package._get_namespaces_as_dict()
50 for uri, prefix in namespaces.iteritems():
51 root.set("xmlns:%s" % prefix, uri)
52 if package.uri:
53 root.set("uri", package.uri)
54
55 self._serialize_meta(package, self.root)
56
57 ximports = SubElement(self.root, "imports")
58 for i in package.own.imports:
59 self._serialize_import(i, ximports)
60 if len(ximports) == 0:
61 self.root.remove(ximports)
62
63 xtags = SubElement(self.root, "tags")
64 for t in package.own.tags:
65 self._serialize_tag(t, xtags)
66 if len(xtags) == 0:
67 self.root.remove(xtags)
68
69 xmedias = SubElement(self.root, "medias")
70 for m in package.own.medias:
71 self._serialize_media(m, xmedias)
72 if len(xmedias) == 0:
73 self.root.remove(xmedias)
74
75 xresources = SubElement(self.root, "resources")
76 for r in package.own.resources:
77 self._serialize_resource(r, xresources)
78 if len(xresources) == 0:
79 self.root.remove(xresources)
80
81 xannotations = SubElement(self.root, "annotations")
82 for a in package.own.annotations:
83 self._serialize_annotation(a, xannotations)
84 if len(xannotations) == 0:
85 self.root.remove(xannotations)
86
87 xrelations = SubElement(self.root, "relations")
88 for r in package.own.relations:
89 self._serialize_relation(r, xrelations)
90 if len(xrelations) == 0:
91 self.root.remove(xrelations)
92
93 xviews = SubElement(self.root, "views")
94 for v in package.own.views:
95 self._serialize_view(v, xviews)
96 if len(xviews) == 0:
97 self.root.remove(xviews)
98
99 xqueries = SubElement(self.root, "queries")
100 for q in package.own.queries:
101 self._serialize_query(q, xqueries)
102 if len(xqueries) == 0:
103 self.root.remove(xqueries)
104
105 xlists = SubElement(self.root, "lists")
106 for L in package.own.lists:
107 self._serialize_list(L, xlists)
108 if len(xlists) == 0:
109 self.root.remove(xlists)
110
111 self._serialize_external_tagging(self.root)
112
113 _indent(self.root)
114 ElementTree(self.root).write(self.file)
115
116
117
127
128
129
135
143
154
156 xL = SubElement(xlists, tagname, id=L.id)
157 xitems = SubElement(xL, "items")
158 for i in L.iter_item_ids():
159 SubElement(xitems, "item", {"id-ref":i})
160 if len(xitems) == 0:
161 xL.remove(xitems)
162 self._serialize_element_tags(L, xL)
163 self._serialize_meta(L, xL)
164
175
181
187
193
200
201
202
203 - def _serialize_content(self, elt, xelt):
204 if elt.content_mimetype != "x-advene/none":
205 xc = SubElement(xelt, "content",
206 mimetype=elt.content_mimetype)
207 if elt.content_model_id:
208 xc.set("model", elt.content_model_id)
209 if elt.content_url:
210
211 xc.set("url", elt.content_url)
212 else:
213 data = elt.content_data
214 if not elt.content_is_textual:
215 data = base64.encodestring(data)
216 xc.set("encoding", "base64")
217 xc.text = data
218
248
255
257 xx = SubElement(xpackage, "external-tag-associations")
258 pairs = self.package._backend.iter_external_tagging(self.package._id)
259 for e, t in pairs:
260 xxt = SubElement(xx, "association", element=e, tag=t)
261 if len(xx) == 0:
262 xpackage.remove(xx)
263
264
266 """from http://effbot.org/zone/element-lib.htm#prettyprint"""
267 i = "\n" + level*" "
268 if len(elem):
269 if not elem.text or not elem.text.strip():
270 elem.text = i + " "
271 for child in elem:
272 _indent(child, level+1)
273 if not child.tail or not child.tail.strip():
274 child.tail = i + " "
275 if not child.tail or not child.tail.strip():
276 child.tail = i
277 else:
278 if level and (not elem.tail or not elem.tail.strip()):
279 elem.tail = i
280
286