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

nextcloud.common.collections.PropertySet._fields()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 1
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
                        setattr(self, prop.attr_name, value)
52
53
    @classmethod
54
    def default_get(cls, key_format='json', **kwargs):
55
        """
56
        Get default values
57
58
        :param key_format: 'json' or 'xml'
59
        :param (any):       values to force (python names)
60
        """
61
        vals = {getattr(v, '%s_key' % key_format): kwargs.get(v.attr_name, v.default_value)
62
                for v in cls._attrs if getattr(v, '%s_key' % key_format, False)}
63
        return vals
64
65
    @classmethod
66
    def build_xml_propfind(cls, instr=None, filter_rules=None, use_default=False, fields=None):
67
        """see SimpleXml.build_propfind_datas
68
69
        :param use_default:   True to use all values specified in PropertySet
70
        """
71
        if use_default:
72
            if not fields:
73
                fields = {k: [] for k in NAMESPACES_MAP.keys()}
74
                for attr in cls._attrs:
75
                    fields[attr.ns].append(attr.xml_key)
76
77
        return SimpleXml.build_propfind_datas(instr=instr, filter_rules=filter_rules,
78
                                              fields=(fields or {}))
79
80
    @classmethod
81
    def build_xml_propupdate(cls, values):
82
        """ see SimpleXml.build_propupdate_datas """
83
        return SimpleXml.build_propupdate_datas(values)
84
85
    @classmethod
86
    def from_response(cls, resp, json_output=None, filtered=None, init_attrs=None):
87
        """ Build list of PropertySet from a NextcloudResponse """
88
        if not resp.is_ok:
89
            resp.data = None
90
            return resp
91
        else:
92
            response_data = resp.data
93
            response_xml_data = SimpleXml.fromstring(response_data)
94
            attr_datas = [cls(xml_data, init_attrs=init_attrs)
95
                          for xml_data in response_xml_data]
96
            if filtered:
97
                if callable(filtered):
98
                    attr_datas = [
99
                        attr_data for attr_data in attr_datas if filtered(attr_data)]
100
            resp.data = attr_datas if not json_output else [
101
                attr_data.as_dict() for attr_data in attr_datas]
102
            return resp
103
104
    def as_dict(self):
105
        """ Return current instance as a {k: val} dict """
106
        attrs = [v.attr_name for v in self._attrs]
107
        return {key: value for key, value in self.__dict__.items() if key in attrs}
108