Statistics
| Branch: | Tag: | Revision:

root / api / emitter.py @ 5c812d1b

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
            "flavor": [ "id", "name", "ram", "disk" ],
27
            "image": [ "id", "name", "updated", "created", "status",
28
                       "serverId", "progress" ],
29
        }
30

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

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

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