Statistics
| Branch: | Tag: | Revision:

root / api / emitter.py @ 1cea389e

History | View | Annotate | Download (2.3 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", "imageId", "name", "flavorId", "hostId",
25
                        "status", "progress", "progress" ],
26
            'ip': ['addr'],
27
            'ip6': ['addr'],
28
            'meta': ['key'],
29
            "flavor": [ "id", "name", "ram", "disk" ],
30
            "image": [ "id", "name", "updated", "created", "status",
31
                       "serverId", "progress" ],
32
        }
33

    
34
    def _to_xml_node(self, doc, nodename, data):
35
        """Recursive method to convert data members to XML nodes."""
36
        result = doc.createElement(nodename)
37
        if type(data) is list:
38
            if nodename.endswith('s'):
39
                singular = nodename[:-1]
40
            else:
41
                singular = 'item'
42
            for item in data:
43
                node = self._to_xml_node(doc, singular, item)
44
                result.appendChild(node)
45
        elif type(data) is dict:
46
            attrs = self._metadata.get(nodename, {})
47
            for k, v in data.items():
48
                if k in attrs:
49
                    result.setAttribute(k, str(v))
50
                else:
51
                    node = self._to_xml_node(doc, k, v)
52
                    result.appendChild(node)
53
        else: # atom
54
            node = doc.createTextNode(str(data))
55
            result.appendChild(node)
56
        return result
57

    
58
    def render(self, request):
59
        data = self.construct()
60
        # We expect data to contain a single key which is the XML root.
61
        root_key = data.keys()[0]
62
        doc = minidom.Document()
63
        node = self._to_xml_node(doc, root_key, data[root_key])
64
        return node.toprettyxml(indent='    ')
65

    
66
Emitter.register('xml', OSXMLEmitter, 'application/xml')
67
Mimer.register(lambda *a: None, ('application/xml',))