Revision b9809f7c

b/api/emitter.py
3 3
# Copyright © 2010 Greek Research and Technology Network
4 4
#
5 5

  
6
from piston.emitters import Emitter, Mimer
6 7
from piston.resource import Resource as BaseResource
8
from xml.dom import minidom
7 9
import re
8 10

  
9 11
_accept_re = re.compile(r'([^\s;,]+)(?:[^,]*?;\s*q=(\d*(?:\.\d+)?))?')
......
30 32

  
31 33
    return result
32 34

  
33
# XXX: works as intended but not used since piston's XMLEmitter doesn't output
34
# XML according to our spec :(
35 35
class Resource(BaseResource):
36 36
    def determine_emitter(self, request, *args, **kwargs):
37 37
        """
......
46 46
        specification.
47 47
        """
48 48

  
49
        em = request.GET.get('format', 'xml')
49
        em = request.GET.get('format', 'json')
50 50
        if 'emitter_format' in kwargs:
51 51
            em = kwargs.pop('emitter_format')
52 52
        elif 'HTTP_ACCEPT' in request.META:
......
59 59
                    break
60 60

  
61 61
        return em
62

  
63
class OSXMLEmitter(Emitter):
64
    """
65
    Custom XML Emitter that handles some special stuff needed by the API.
66

  
67
    Shamelessly stolen^Wborrowed code (sans Piston integration) by OpenStack's
68
    Nova project and hence:
69

  
70
    Copyright 2010 United States Government as represented by the
71
    Administrator of the National Aeronautics and Space Administration.
72
    Copyright 2010 OpenStack LLC.
73

  
74
    and licensed under the Apache License, Version 2.0
75
    """
76

  
77
    _metadata = {
78
            "server": [ "id", "imageId", "name", "flavorId", "hostId",
79
                        "status", "progress", "progress" ],
80
            "flavor": [ "id", "name", "ram", "disk" ],
81
            "image": [ "id", "name", "updated", "created", "status",
82
                       "serverId", "progress" ],
83
        }
84

  
85
    def _to_xml_node(self, doc, nodename, data):
86
        """Recursive method to convert data members to XML nodes."""
87
        result = doc.createElement(nodename)
88
        if type(data) is list:
89
            if nodename.endswith('s'):
90
                singular = nodename[:-1]
91
            else:
92
                singular = 'item'
93
            for item in data:
94
                node = self._to_xml_node(doc, singular, item)
95
                result.appendChild(node)
96
        elif type(data) is dict:
97
            attrs = self._metadata.get(nodename, {})
98
            for k, v in data.items():
99
                if k in attrs:
100
                    result.setAttribute(k, str(v))
101
                else:
102
                    node = self._to_xml_node(doc, k, v)
103
                    result.appendChild(node)
104
        else: # atom
105
            node = doc.createTextNode(str(data))
106
            result.appendChild(node)
107
        return result
108

  
109
    def render(self, request):
110
        data = self.construct()
111
        # We expect data to contain a single key which is the XML root.
112
        root_key = data.keys()[0]
113
        doc = minidom.Document()
114
        node = self._to_xml_node(doc, root_key, data[root_key])
115
        return node.toprettyxml(indent='    ')
116

  
117
Emitter.register('xml', OSXMLEmitter, 'application/xml')
118
Mimer.register(lambda *a: None, ('application/xml',))
b/api/faults.py
77 77
        m['details'] = ''
78 78

  
79 79
        # piston > 0.2.2 does the serialization for us, but be compatible
80
        # XXX: this won't work when we start supporting XML
80
        # 'till the next version gets released. XXX: this doesn't do XML!
81 81
        message = simplejson.dumps({ attr: m }, ensure_ascii=False, indent=4)
82 82
        code = m['code']
83 83
        response = HttpResponse(message, status=code)
b/api/urls.py
4 4
#
5 5

  
6 6
from django.conf.urls.defaults import *
7
from piston.resource import Resource
7
from synnefo.api.emitter import Resource
8 8
from synnefo.api.handlers import *
9 9
from synnefo.api.authentication import TokenAuthentication
10 10
from synnefo.api.faults import fault

Also available in: Unified diff