renderers.py 2.04 KB
Newer Older
1
2
3
4
import xml.etree.ElementTree as ET

from rest_framework import renderers

5
6
import funkwhale_api

7
8
9
10
11
12

class SubsonicJSONRenderer(renderers.JSONRenderer):
    def render(self, data, accepted_media_type=None, renderer_context=None):
        if not data:
            # when stream view is called, we don't have any data
            return super().render(data, accepted_media_type, renderer_context)
13
14
15
16
17
18
19
20
        final = {
            "subsonic-response": {
                "status": "ok",
                "version": "1.16.0",
                "type": "funkwhale",
                "funkwhale-version": funkwhale_api.__version__,
            }
        }
Eliot Berriot's avatar
Eliot Berriot committed
21
22
        final["subsonic-response"].update(data)
        if "error" in final:
23
            # an error was returned
Eliot Berriot's avatar
Eliot Berriot committed
24
            final["subsonic-response"]["status"] = "failed"
25
26
27
28
        return super().render(final, accepted_media_type, renderer_context)


class SubsonicXMLRenderer(renderers.JSONRenderer):
Eliot Berriot's avatar
Eliot Berriot committed
29
    media_type = "text/xml"
30
31
32
33
34
35

    def render(self, data, accepted_media_type=None, renderer_context=None):
        if not data:
            # when stream view is called, we don't have any data
            return super().render(data, accepted_media_type, renderer_context)
        final = {
Eliot Berriot's avatar
Eliot Berriot committed
36
37
38
            "xmlns": "http://subsonic.org/restapi",
            "status": "ok",
            "version": "1.16.0",
39
40
        }
        final.update(data)
Eliot Berriot's avatar
Eliot Berriot committed
41
        if "error" in final:
42
            # an error was returned
Eliot Berriot's avatar
Eliot Berriot committed
43
44
45
46
47
            final["status"] = "failed"
        tree = dict_to_xml_tree("subsonic-response", final)
        return b'<?xml version="1.0" encoding="UTF-8"?>\n' + ET.tostring(
            tree, encoding="utf-8"
        )
48
49
50
51
52
53
54
55
56
57
58
59
60


def dict_to_xml_tree(root_tag, d, parent=None):
    root = ET.Element(root_tag)
    for key, value in d.items():
        if isinstance(value, dict):
            root.append(dict_to_xml_tree(key, value, parent=root))
        elif isinstance(value, list):
            for obj in value:
                root.append(dict_to_xml_tree(key, obj, parent=root))
        else:
            root.set(key, str(value))
    return root