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

Property._py_name_to_xml_name()   A

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nop 2
1
# -*- coding: utf-8 -*-
2
"""
3
Define properties types that can be used one OwnCloud/NextCloud elements
4
5
6
How to define a new property namespace. Example:
7
>>> class NCProp(Property):
8
>>>    # define the namespace code with the namespace value
9
>>>     namespace = ('nc', 'http://nextcloud.org/ns')
10
>>>    # choose which attribute name is given by default on PropertySet
11
>>>    _name_convention = {
12
>>>        # xml     :  python
13
>>>        'xmly-attr-name': 'cute_attr_name',
14
>>>    }  # Note: by default, all '-' are already replaced by '_'
15
16
"""
17
import six
18
19
NAMESPACES_MAP = {}
20
NAMESPACES_CLASSES = {}
21
22
23
class MetaProperty(type):
24
    def __new__(meta, name, bases, attrs):
25
        cls = type.__new__(meta, name, bases, attrs)
26
        if (cls.namespace):
27
            NAMESPACES_MAP[cls.namespace[0]] = cls.namespace[1]
28
            NAMESPACES_CLASSES[cls.namespace[0]] = cls
29
        return cls
30
31
32
class Property(object, six.with_metaclass(MetaProperty)):
33
    """
34
    Define an element property, and naming of resulting python attribute
35
36
    :param xml_name:        xml property name (prefixed with 'ns:' i.e. namespace)
37
    :param json:            json property name
38
    :param default:         default value (value or function without args)
39
    :param parse_xml_value: a function that take xml.etree.ElementTree and
40
                            return value of the property
41
    """
42
    namespace = None
43
    _name_convention = {}
44
45
    def __init__(self, xml_name, json=None, default=None, parse_xml_value=None):
46
        if ':' in xml_name:
47
            (self.ns, self.xml_key) = xml_name.split(':')
48
            self._name_convention = NAMESPACES_CLASSES[self.ns]
49
        else:
50
            self.xml_key = xml_name
51
            if self.namespace:
52
                self.ns = self.namespace[0]
53
54
        self.attr_name = self._xml_name_to_py_name(self.xml_key)
55
        self.json_key = json
56
        self.default_val = default
57
        self.parse_xml_value = parse_xml_value
58
59
    @classmethod
60
    def _xml_name_to_py_name(cls, name):
61
        if name in cls._name_convention:
62
            return cls._name_convention[name]
63
        else:
64
            return name.replace('-', '_')
65
66
    @classmethod
67
    def _py_name_to_xml_name(cls, name):
68
        _reversed_convention = {v: k for k, v in cls._name_convention.items()}
69
        if name in _reversed_convention:
70
            return _reversed_convention[name]
71
        else:
72
            return name.replace('_', '-')
73
74
    @property
75
    def default_value(self):
76
        """ Fetch default value """
77
        if callable(self.default_val):
78
            return self.default_val()
79
        else:
80
            return self.default_val
81
82
    def get_value(self, xml=None):
83
        """
84
        Fetch value from input data
85
86
        :param xml:  xml.etree.ElementTree node
87
        :returns:    python value
88
        """
89
        if xml is not None:
90
            if self.parse_xml_value:
91
                return self.parse_xml_value(xml)
92
            else:
93
                return xml.text
94
95
96
class DProp(Property):
97
    """ DAV property """
98
    namespace = ('d', 'DAV:')
99
100
    _name_convention = {
101
        'getlastmodified': 'last_modified',
102
        'getetag': 'etag',
103
        'getcontenttype': 'content_type',
104
        'resourcetype': 'resource_type',
105
                        'getcontentlength': 'content_length'
106
    }
107
108
class OCProp(Property):
109
    """ OwnCloud property """
110
    namespace = ('oc', 'http://owncloud.org/ns')
111
112
    _name_convention = {
113
        'fileid': 'file_id',
114
        'checksums': 'check_sums'
115
    }
116
117
118
class NCProp(Property):
119
    """ NextCloud property """
120
    namespace = ('nc', 'http://nextcloud.org/ns')
121