Passed
Pull Request — master (#69)
by
unknown
01:25
created

PropertySet.from_response()   A

Complexity

Conditions 5

Size

Total Lines 18
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 18
rs 9.1333
c 0
b 0
f 0
cc 5
nop 5
1
# -*- coding: utf-8 -*-
2
"""
3
Define generic request/result class
4
common to File and Tag
5
"""
6
import re
7
from nextcloud.common.simplexml import SimpleXml
8
from nextcloud.common.properties import NAMESPACES_MAP
9
10
11
class PropertySet(object):
12
    """
13
    Set of nextcloud.common.properties.Prop
14
    defined in _attrs class variable
15
    """
16
    SUCCESS_STATUS = 'HTTP/1.1 200 OK'
17
    COLLECTION_RESOURCE_TYPE = 'collection'
18
    _attrs = []
19
20
    @property
21
    def _fields(self):
22
        return [v.attr_name for v in self._attrs]
23
24
    @property
25
    def _properties(self):
26
        return [v.xml_key for v in self._attrs]
27
28
    @classmethod
29
    def _fetch_property(cls, key, attr='xml_key'):
30
        for k in cls._attrs:
31
            if getattr(k, attr) == key:
32
                return k
33
34
    def __init__(self, xml_data, init_attrs=False):
35
        if init_attrs:
36
            for attr in self._attrs:
37
                setattr(self, attr.attr_name, None)
38
39
        self.href = xml_data.find('d:href', NAMESPACES_MAP).text
40
        for propstat in xml_data.iter('{DAV:}propstat'):
41
            if propstat.find('d:status', NAMESPACES_MAP).text != self.SUCCESS_STATUS:
42
                pass
43
            else:
44
                for xml_property in propstat.find('d:prop', NAMESPACES_MAP):
45
                    property_name = re.sub('{.*}', '', xml_property.tag)
46
                    prop = self._fetch_property(property_name)
47
                    if not prop:
48
                        pass
49
                    else:
50
                        value = prop.get_value(xml=xml_property)
51
                        print(prop.__repr__())
52
                        setattr(self, prop.attr_name, value)
53
54
    @classmethod
55
    def default_get(cls, key_format='json', **kwargs):
56
        """
57
        Get default values
58
59
        :param key_format: 'json' or 'xml'
60
        :param (any):       values to force (python names)
61
        """
62
        vals = {getattr(v, '%s_key' % key_format): kwargs.get(v.attr_name, v.default_value)
63
                for v in cls._attrs if getattr(v, '%s_key' % key_format, False)}
64
        return vals
65
66
    @classmethod
67
    def build_xml_propfind(cls, instr=None, filter_rules=None, use_default=False, fields=None):
68
        """see SimpleXml.build_propfind_datas
69
70
        :param use_default:   True to use all values specified in PropertySet
71
        """
72
        if use_default:
73
            if not fields:
74
                fields = {k: [] for k in NAMESPACES_MAP.keys()}
75
                for attr in cls._attrs:
76
                    fields[attr.ns].append(attr.xml_key)
77
78
        return SimpleXml.build_propfind_datas(instr=instr, filter_rules=filter_rules,
79
                                              fields=(fields or {}))
80
81
    @classmethod
82
    def build_xml_propupdate(cls, values):
83
        """ see SimpleXml.build_propupdate_datas """
84
        return SimpleXml.build_propupdate_datas(values)
85
86
    @classmethod
87
    def from_response(cls, resp, json_output=None, filtered=None, init_attrs=None):
88
        """ Build list of PropertySet from a NextcloudResponse """
89
        if not resp.is_ok:
90
            resp.data = None
91
            return resp
92
        else:
93
            response_data = resp.data
94
            response_xml_data = SimpleXml.fromstring(response_data)
95
            attr_datas = [cls(xml_data, init_attrs=init_attrs)
96
                          for xml_data in response_xml_data]
97
            if filtered:
98
                if callable(filtered):
99
                    attr_datas = [
100
                        attr_data for attr_data in attr_datas if filtered(attr_data)]
101
            resp.data = attr_datas if not json_output else [
102
                attr_data.as_dict() for attr_data in attr_datas]
103
            return resp
104
105
    def as_dict(self):
106
        """ Return current instance as a {k: val} dict """
107
        attrs = [v.attr_name for v in self._attrs]
108
        return {key: value for key, value in self.__dict__.items() if key in attrs}
109