Statistics
| Branch: | Tag: | Revision:

root / api / emitter.py @ b016b476

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',))