Passed
Push — master ( 01a50b...c59786 )
by Fabio
01:14
created

benedict.dicts.io.IODict._decode()   A

Complexity

Conditions 4

Size

Total Lines 19
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 19
rs 9.6
c 0
b 0
f 0
cc 4
nop 3
1
# -*- coding: utf-8 -*-
2
3
from benedict.utils import io_util
4
5
from six import string_types, text_type
6
7
8
class IODict(dict):
9
10
    def __init__(self, *args, **kwargs):
11
        # if first argument is data-string,
12
        # try to decode it using all decoders.
13
        if len(args) and isinstance(args[0], string_types):
14
            d = IODict._from_any_data_string(args[0])
15
            if d and isinstance(d, dict):
16
                args = list(args)
17
                args[0] = d
18
                args = tuple(args)
19
            else:
20
                raise ValueError('Invalid string data input.')
21
        super(IODict, self).__init__(*args, **kwargs)
22
23
    @staticmethod
24
    def _decode(s, decoder, **kwargs):
25
        d = None
26
        try:
27
            content = io_util.read_content(s)
28
            # decode content using the given decoder
29
            data = decoder(content, **kwargs)
30
            if isinstance(data, dict):
31
                d = data
32
            elif isinstance(data, list):
33
                # force list to dict
34
                d = { 'values':data }
35
            else:
36
                raise ValueError(
37
                    'Invalid data type: {}, expected dict or list.'.format(type(data)))
38
        except Exception as e:
39
            raise ValueError(
40
                'Invalid data or url or filepath input argument: {}\n{}'.format(s, text_type(e)))
41
        return d
42
43
    @staticmethod
44
    def _encode(d, encoder, filepath=None, **kwargs):
45
        s = encoder(d, **kwargs)
46
        if filepath:
47
            io_util.write_file(filepath, s)
48
        return s
49
50
    @staticmethod
51
    def _from_any_data_string(s, **kwargs):
52
        try:
53
            d = IODict.from_base64(s, **kwargs)
54
            return d
55
        except ValueError:
56
            pass
57
        try:
58
            d = IODict.from_json(s, **kwargs)
59
            return d
60
        except ValueError:
61
            pass
62
        try:
63
            d = IODict.from_toml(s, **kwargs)
64
            return d
65
        except ValueError:
66
            pass
67
        try:
68
            d = IODict.from_xml(s, **kwargs)
69
            return d
70
        except ValueError:
71
            pass
72
        try:
73
            d = IODict.from_yaml(s, **kwargs)
74
            return d
75
        except ValueError:
76
            pass
77
78
    @staticmethod
79
    def from_base64(s, **kwargs):
80
        return IODict._decode(s,
81
            decoder=io_util.decode_base64, **kwargs)
82
83
    @staticmethod
84
    def from_json(s, **kwargs):
85
        return IODict._decode(s,
86
            decoder=io_util.decode_json, **kwargs)
87
88
    @staticmethod
89
    def from_toml(s, **kwargs):
90
        return IODict._decode(s,
91
            decoder=io_util.decode_toml, **kwargs)
92
93
    @staticmethod
94
    def from_xml(s, **kwargs):
95
        return IODict._decode(s,
96
            decoder=io_util.decode_xml, **kwargs)
97
98
    @classmethod
99
    def from_yaml(cls, s, **kwargs):
100
        return IODict._decode(s,
101
            decoder=io_util.decode_yaml, **kwargs)
102
103
    def to_base64(self, filepath=None, **kwargs):
104
        return IODict._encode(self,
105
            encoder=io_util.encode_base64,
106
            filepath=filepath, **kwargs)
107
108
    def to_json(self, filepath=None, **kwargs):
109
        return IODict._encode(self,
110
            encoder=io_util.encode_json,
111
            filepath=filepath, **kwargs)
112
113
    def to_toml(self, filepath=None, **kwargs):
114
        return IODict._encode(self,
115
            encoder=io_util.encode_toml,
116
            filepath=filepath, **kwargs)
117
118
    def to_xml(self, filepath=None, **kwargs):
119
        return IODict._encode(self,
120
            encoder=io_util.encode_xml,
121
            filepath=filepath, **kwargs)
122
123
    def to_yaml(self, filepath=None, **kwargs):
124
        return IODict._encode(self,
125
            encoder=io_util.encode_yaml,
126
            filepath=filepath, **kwargs)
127