Completed
Push — master ( 1c4121...07028b )
by Fabio
03:58
created

benedict.dicts.io   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 26
eloc 101
dl 0
loc 129
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A IODict._decode() 0 19 4
A IODict.__init__() 0 12 5
A IODict._encode() 0 6 2
A IODict.to_yaml() 0 4 1
A IODict.to_xml() 0 4 1
A IODict.to_toml() 0 4 1
A IODict.from_json() 0 4 1
A IODict.from_toml() 0 4 1
A IODict.to_json() 0 4 1
A IODict.from_xml() 0 4 1
A IODict.from_query_string() 0 4 1
A IODict.from_base64() 0 5 1
A IODict.to_base64() 0 5 1
A IODict._from_any_data_string() 0 17 3
A IODict.from_yaml() 0 4 1
A IODict.to_query_string() 0 4 1
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], **kwargs)
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
        funcs = [
53
            IODict.from_base64,
54
            IODict.from_json,
55
            IODict.from_query_string,
56
            IODict.from_toml,
57
            IODict.from_xml,
58
            IODict.from_yaml,
59
        ]
60
        for f in funcs:
61
            try:
62
                options = kwargs.copy()
63
                d = f(s, **options)
64
                return d
65
            except ValueError:
66
                pass
67
68
    @staticmethod
69
    def from_base64(s, format='json', **kwargs):
70
        kwargs['format'] = format
71
        return IODict._decode(s,
72
            decoder=io_util.decode_base64, **kwargs)
73
74
    @staticmethod
75
    def from_json(s, **kwargs):
76
        return IODict._decode(s,
77
            decoder=io_util.decode_json, **kwargs)
78
79
    @staticmethod
80
    def from_query_string(s, **kwargs):
81
        return IODict._decode(s,
82
            decoder=io_util.decode_query_string, **kwargs)
83
84
    @staticmethod
85
    def from_toml(s, **kwargs):
86
        return IODict._decode(s,
87
            decoder=io_util.decode_toml, **kwargs)
88
89
    @staticmethod
90
    def from_xml(s, **kwargs):
91
        return IODict._decode(s,
92
            decoder=io_util.decode_xml, **kwargs)
93
94
    @staticmethod
95
    def from_yaml(s, **kwargs):
96
        return IODict._decode(s,
97
            decoder=io_util.decode_yaml, **kwargs)
98
99
    def to_base64(self, filepath=None, format='json', **kwargs):
100
        kwargs['format'] = format
101
        return IODict._encode(self,
102
            encoder=io_util.encode_base64,
103
            filepath=filepath, **kwargs)
104
105
    def to_json(self, filepath=None, **kwargs):
106
        return IODict._encode(self,
107
            encoder=io_util.encode_json,
108
            filepath=filepath, **kwargs)
109
110
    def to_query_string(self, filepath=None, **kwargs):
111
        return IODict._encode(self,
112
            encoder=io_util.encode_query_string,
113
            filepath=filepath, **kwargs)
114
115
    def to_toml(self, filepath=None, **kwargs):
116
        return IODict._encode(self,
117
            encoder=io_util.encode_toml,
118
            filepath=filepath, **kwargs)
119
120
    def to_xml(self, filepath=None, **kwargs):
121
        return IODict._encode(self,
122
            encoder=io_util.encode_xml,
123
            filepath=filepath, **kwargs)
124
125
    def to_yaml(self, filepath=None, **kwargs):
126
        return IODict._encode(self,
127
            encoder=io_util.encode_yaml,
128
            filepath=filepath, **kwargs)
129