1try:
2    import json
3except ImportError:
4    import simplejson as json
5
6try:
7    from UserList import UserList
8except ImportError:
9    from collections import UserList
10
11
12class Resource(object):
13    """Object wrapper for resources.
14
15    Provides an object interface to resources returned by the Soundcloud API.
16    """
17    def __init__(self, obj):
18        self.obj = obj
19        if hasattr(self, 'origin'):
20            self.origin = Resource(self.origin)
21
22    def __getstate__(self):
23        return self.obj.items()
24
25    def __setstate__(self, items):
26        if not hasattr(self, 'obj'):
27            self.obj = {}
28        for key, val in items:
29            self.obj[key] = val
30
31    def __getattr__(self, name):
32        if name in self.obj:
33            return self.obj.get(name)
34        raise AttributeError
35
36    def fields(self):
37        return self.obj
38
39    def keys(self):
40        return self.obj.keys()
41
42
43class ResourceList(UserList):
44    """Object wrapper for lists of resources."""
45    def __init__(self, resources=[]):
46        data = [Resource(resource) for resource in resources]
47        super(ResourceList, self).__init__(data)
48
49
50def wrapped_resource(response):
51    """Return a response wrapped in the appropriate wrapper type.
52
53    Lists will be returned as a ```ResourceList``` instance,
54    dicts will be returned as a ```Resource``` instance.
55    """
56    # decode response text, assuming utf-8 if unset
57    response_content = response.content.decode(response.encoding or 'utf-8')
58
59    try:
60        content = json.loads(response_content)
61    except ValueError:
62        # not JSON
63        content = response_content
64    if isinstance(content, list):
65        result = ResourceList(content)
66    else:
67        result = Resource(content)
68        if hasattr(result, 'collection'):
69            result.collection = ResourceList(result.collection)
70    result.raw_data = response_content
71
72    for attr in ('encoding', 'url', 'status_code', 'reason'):
73        setattr(result, attr, getattr(response, attr))
74
75    return result
76