root / api / emitter.py @ b9a77976
History | View | Annotate | Download (2.6 kB)
1 |
# vim: ts=4 sts=4 et ai sw=4 fileencoding=utf-8
|
---|---|
2 |
#
|
3 |
# Copyright © 2010 Greek Research and Technology Network
|
4 |
#
|
5 |
|
6 |
from xml.dom import minidom |
7 |
from piston.emitters import Emitter, Mimer |
8 |
|
9 |
class OSXMLEmitter(Emitter): |
10 |
"""
|
11 |
Custom XML Emitter that handles some special stuff needed by the API.
|
12 |
|
13 |
Shamelessly stolen^Wborrowed code (sans Piston integration) by OpenStack's
|
14 |
Nova project and hence:
|
15 |
|
16 |
Copyright 2010 United States Government as represented by the
|
17 |
Administrator of the National Aeronautics and Space Administration.
|
18 |
Copyright 2010 OpenStack LLC.
|
19 |
|
20 |
and licensed under the Apache License, Version 2.0
|
21 |
"""
|
22 |
|
23 |
_metadata = { |
24 |
"server": [ "id", "imageRef", "name", "flavorRef", "hostId", |
25 |
"status", "progress", "progress", "description", "created", "updated" ], |
26 |
'ip': ['addr'], |
27 |
'ip6': ['addr'], |
28 |
'meta': ['key'], |
29 |
"flavor": [ "id", "name", "ram", "disk", "cpu" ], |
30 |
"image": [ "id", "name", "updated", "created", "status", |
31 |
"serverId", "progress", "size", "description"], |
32 |
"group": [ "id", "name", "server_id"], |
33 |
|
34 |
} |
35 |
|
36 |
def _to_xml_node(self, doc, nodename, data): |
37 |
"""Recursive method to convert data members to XML nodes."""
|
38 |
result = doc.createElement(nodename) |
39 |
if type(data) is list: |
40 |
if nodename.endswith('s'): |
41 |
singular = nodename[:-1]
|
42 |
else:
|
43 |
singular = 'item'
|
44 |
for item in data: |
45 |
node = self._to_xml_node(doc, singular, item)
|
46 |
result.appendChild(node) |
47 |
elif type(data) is dict: |
48 |
attrs = self._metadata.get(nodename, {})
|
49 |
for k, v in data.items(): |
50 |
if k in attrs: |
51 |
#protect from case where unicode with ascii chars is casted to str
|
52 |
v = v.__class__ == str and v.decode("utf8") or unicode(v) |
53 |
result.setAttribute(k, v) |
54 |
else:
|
55 |
node = self._to_xml_node(doc, k, v)
|
56 |
result.appendChild(node) |
57 |
else: # atom |
58 |
node = doc.createTextNode(str(data))
|
59 |
result.appendChild(node) |
60 |
return result
|
61 |
|
62 |
def render(self, request): |
63 |
data = self.construct()
|
64 |
# We expect data to contain a single key which is the XML root.
|
65 |
root_key = data.keys()[0]
|
66 |
doc = minidom.Document() |
67 |
node = self._to_xml_node(doc, root_key, data[root_key])
|
68 |
return node.toprettyxml(indent=' ') |
69 |
|
70 |
Emitter.register('xml', OSXMLEmitter, 'application/xml') |
71 |
Mimer.register(lambda *a: None, ('application/xml',)) |