Statistics
| Branch: | Tag: | Revision:

root / api / emitter.py @ b016b476

History | View | Annotate | Download (2.6 kB)

1 00b4f1be Faidon Liambotis
# vim: ts=4 sts=4 et ai sw=4 fileencoding=utf-8
2 00b4f1be Faidon Liambotis
#
3 00b4f1be Faidon Liambotis
# Copyright © 2010 Greek Research and Technology Network
4 00b4f1be Faidon Liambotis
#
5 00b4f1be Faidon Liambotis
6 c3e8f508 Faidon Liambotis
from xml.dom import minidom
7 b9809f7c Faidon Liambotis
from piston.emitters import Emitter, Mimer
8 b9809f7c Faidon Liambotis
9 b9809f7c Faidon Liambotis
class OSXMLEmitter(Emitter):
10 b9809f7c Faidon Liambotis
    """
11 b9809f7c Faidon Liambotis
    Custom XML Emitter that handles some special stuff needed by the API.
12 b9809f7c Faidon Liambotis

13 b9809f7c Faidon Liambotis
    Shamelessly stolen^Wborrowed code (sans Piston integration) by OpenStack's
14 b9809f7c Faidon Liambotis
    Nova project and hence:
15 b9809f7c Faidon Liambotis

16 b9809f7c Faidon Liambotis
    Copyright 2010 United States Government as represented by the
17 b9809f7c Faidon Liambotis
    Administrator of the National Aeronautics and Space Administration.
18 b9809f7c Faidon Liambotis
    Copyright 2010 OpenStack LLC.
19 b9809f7c Faidon Liambotis

20 b9809f7c Faidon Liambotis
    and licensed under the Apache License, Version 2.0
21 b9809f7c Faidon Liambotis
    """
22 b9809f7c Faidon Liambotis
23 b9809f7c Faidon Liambotis
    _metadata = {
24 b335768e Markos Gogoulos
            "server": [ "id", "imageRef", "name", "flavorRef", "hostId",
25 b335768e Markos Gogoulos
                        "status", "progress", "progress", "description", "created", "updated" ],
26 e336bde6 Markos Gogoulos
            'ip': ['addr'],
27 1cea389e Markos Gogoulos
            'ip6': ['addr'],
28 e336bde6 Markos Gogoulos
            'meta': ['key'],
29 9625c3b3 Markos Gogoulos
            "flavor": [ "id", "name", "ram", "disk", "cpu" ],
30 b9809f7c Faidon Liambotis
            "image": [ "id", "name", "updated", "created", "status",
31 f1684357 Markos Gogoulos
                       "serverId", "progress", "size", "description"],
32 59cee068 Markos Gogoulos
            "group": [ "id", "name", "server_id"],
33 59cee068 Markos Gogoulos
34 b9809f7c Faidon Liambotis
        }
35 b9809f7c Faidon Liambotis
36 b9809f7c Faidon Liambotis
    def _to_xml_node(self, doc, nodename, data):
37 b9809f7c Faidon Liambotis
        """Recursive method to convert data members to XML nodes."""
38 b9809f7c Faidon Liambotis
        result = doc.createElement(nodename)
39 b9809f7c Faidon Liambotis
        if type(data) is list:
40 b9809f7c Faidon Liambotis
            if nodename.endswith('s'):
41 b9809f7c Faidon Liambotis
                singular = nodename[:-1]
42 b9809f7c Faidon Liambotis
            else:
43 b9809f7c Faidon Liambotis
                singular = 'item'
44 b9809f7c Faidon Liambotis
            for item in data:
45 b9809f7c Faidon Liambotis
                node = self._to_xml_node(doc, singular, item)
46 b9809f7c Faidon Liambotis
                result.appendChild(node)
47 b9809f7c Faidon Liambotis
        elif type(data) is dict:
48 b9809f7c Faidon Liambotis
            attrs = self._metadata.get(nodename, {})
49 b9809f7c Faidon Liambotis
            for k, v in data.items():
50 b9809f7c Faidon Liambotis
                if k in attrs:
51 72756a5e Markos Gogoulos
                    #protect from case where unicode with ascii chars is casted to str
52 72756a5e Markos Gogoulos
                    v = v.__class__ == str and v.decode("utf8") or unicode(v)
53 72756a5e Markos Gogoulos
                    result.setAttribute(k, v)                    
54 b9809f7c Faidon Liambotis
                else:
55 b9809f7c Faidon Liambotis
                    node = self._to_xml_node(doc, k, v)
56 b9809f7c Faidon Liambotis
                    result.appendChild(node)
57 b9809f7c Faidon Liambotis
        else: # atom
58 b9809f7c Faidon Liambotis
            node = doc.createTextNode(str(data))
59 b9809f7c Faidon Liambotis
            result.appendChild(node)
60 b9809f7c Faidon Liambotis
        return result
61 b9809f7c Faidon Liambotis
62 b9809f7c Faidon Liambotis
    def render(self, request):
63 b9809f7c Faidon Liambotis
        data = self.construct()
64 b9809f7c Faidon Liambotis
        # We expect data to contain a single key which is the XML root.
65 b9809f7c Faidon Liambotis
        root_key = data.keys()[0]
66 b9809f7c Faidon Liambotis
        doc = minidom.Document()
67 b9809f7c Faidon Liambotis
        node = self._to_xml_node(doc, root_key, data[root_key])
68 b9809f7c Faidon Liambotis
        return node.toprettyxml(indent='    ')
69 b9809f7c Faidon Liambotis
70 b9809f7c Faidon Liambotis
Emitter.register('xml', OSXMLEmitter, 'application/xml')
71 b9809f7c Faidon Liambotis
Mimer.register(lambda *a: None, ('application/xml',))