Passed
Push — master ( 81ff45...b46a87 )
by Fabio
01:47
created

benedict.dicts.io.io_dict.IODict.to_ini()   A

Complexity

Conditions 1

Size

Total Lines 9
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 1
nop 2
1
# -*- coding: utf-8 -*-
2
3
from benedict.dicts.base import BaseDict
4
from benedict.dicts.io import io_util
5
from benedict.utils import type_util
6
7
8
class IODict(BaseDict):
9
10
    def __init__(self, *args, **kwargs):
11
        """
12
        Constructs a new instance.
13
        """
14
        # if first argument is data-string, url or filepath try to decode it.
15
        # use 'format' kwarg to specify the decoder to use, default 'json'.
16
        if len(args) == 1 and type_util.is_string(args[0]):
17
            d = IODict._decode_init(args[0], **kwargs)
18
            super(IODict, self).__init__(d)
19
            return
20
        super(IODict, self).__init__(*args, **kwargs)
21
22
    @staticmethod
23
    def _decode_init(s, **kwargs):
24
        autodetected_format = io_util.autodetect_format(s)
25
        default_format = autodetected_format or 'json'
26
        format = kwargs.pop('format', default_format).lower()
27
        if format in ['b64', 'base64']:
28
            kwargs.setdefault('subformat', 'json')
29
        # decode data-string and initialize with dict data.
30
        return IODict._decode(s, format, **kwargs)
31
32
    @staticmethod
33
    def _decode(s, format, **kwargs):
34
        try:
35
            content = io_util.read_content(s)
36
            # decode content using the given format
37
            data = io_util.decode(content, format, **kwargs)
38
            if type_util.is_dict(data):
39
                return data
40
            elif type_util.is_list(data):
41
                # force list to dict
42
                return {'values': data}
43
            else:
44
                raise ValueError(
45
                    'Invalid data type: {}, expected dict or list.'.format(
46
                        type(data)))
47
        except Exception as e:
48
            raise ValueError(
49
                'Invalid data or url or filepath argument: {}\n{}'.format(
50
                    s, e))
51
52
    @staticmethod
53
    def _encode(d, format, **kwargs):
54
        filepath = kwargs.pop('filepath', None)
55
        s = io_util.encode(d, format, **kwargs)
56
        if filepath:
57
            io_util.write_file(filepath, s)
58
        return s
59
60
    @classmethod
61
    def from_base64(cls, s, subformat='json', encoding='utf-8', **kwargs):
62
        """
63
        Load and decode Base64 data from url, filepath or data-string.
64
        Data is decoded according to subformat and encoding.
65
        Decoder specific options can be passed using kwargs.
66
        Return a new dict instance. A ValueError is raised in case of failure.
67
        """
68
        kwargs['subformat'] = subformat
69
        kwargs['encoding'] = encoding
70
        return cls(s, format='base64', **kwargs)
71
72
    @classmethod
73
    def from_csv(cls, s, columns=None, columns_row=True, **kwargs):
74
        """
75
        Load and decode CSV data from url, filepath or data-string.
76
        Decoder specific options can be passed using kwargs:
77
        https://docs.python.org/3/library/csv.html
78
        Return a new dict instance. A ValueError is raised in case of failure.
79
        """
80
        kwargs['columns'] = columns
81
        kwargs['columns_row'] = columns_row
82
        return cls(s, format='csv', **kwargs)
83
84
    @classmethod
85
    def from_ini(cls, s, **kwargs):
86
        """
87
        Load and decode INI data from url, filepath or data-string.
88
        Decoder specific options can be passed using kwargs:
89
        https://docs.python.org/3/library/configparser.html
90
        Return a new dict instance. A ValueError is raised in case of failure.
91
        """
92
        return cls(s, format='ini', **kwargs)
93
94
    @classmethod
95
    def from_json(cls, s, **kwargs):
96
        """
97
        Load and decode JSON data from url, filepath or data-string.
98
        Decoder specific options can be passed using kwargs:
99
        https://docs.python.org/3/library/json.html
100
        Return a new dict instance. A ValueError is raised in case of failure.
101
        """
102
        return cls(s, format='json', **kwargs)
103
104
    @classmethod
105
    def from_pickle(cls, s, **kwargs):
106
        """
107
        Load and decode a pickle encoded in Base64 format data from url, filepath or data-string.
108
        Decoder specific options can be passed using kwargs:
109
        https://docs.python.org/3/library/pickle.html
110
        Return a new dict instance. A ValueError is raised in case of failure.
111
        """
112
        return cls(s, format='pickle', **kwargs)
113
114
    @classmethod
115
    def from_plist(cls, s, **kwargs):
116
        """
117
        Load and decode p-list data from url, filepath or data-string.
118
        Decoder specific options can be passed using kwargs:
119
        https://docs.python.org/3/library/plistlib.html
120
        Return a new dict instance. A ValueError is raised in case of failure.
121
        """
122
        return cls(s, format='plist', **kwargs)
123
124
    @classmethod
125
    def from_query_string(cls, s, **kwargs):
126
        """
127
        Load and decode query-string from url, filepath or data-string.
128
        Return a new dict instance. A ValueError is raised in case of failure.
129
        """
130
        return cls(s, format='query_string', **kwargs)
131
132
    @classmethod
133
    def from_toml(cls, s, **kwargs):
134
        """
135
        Load and decode TOML data from url, filepath or data-string.
136
        Decoder specific options can be passed using kwargs:
137
        https://pypi.org/project/toml/
138
        Return a new dict instance. A ValueError is raised in case of failure.
139
        """
140
        return cls(s, format='toml', **kwargs)
141
142
    @classmethod
143
    def from_xml(cls, s, **kwargs):
144
        """
145
        Load and decode XML data from url, filepath or data-string.
146
        Decoder specific options can be passed using kwargs:
147
        https://github.com/martinblech/xmltodict
148
        Return a new dict instance. A ValueError is raised in case of failure.
149
        """
150
        return cls(s, format='xml', **kwargs)
151
152
    @classmethod
153
    def from_yaml(cls, s, **kwargs):
154
        """
155
        Load and decode YAML data from url, filepath or data-string.
156
        Decoder specific options can be passed using kwargs:
157
        https://pyyaml.org/wiki/PyYAMLDocumentation
158
        Return a new dict instance. A ValueError is raised in case of failure.
159
        """
160
        return cls(s, format='yaml', **kwargs)
161
162
    def to_base64(self, subformat='json', encoding='utf-8', **kwargs):
163
        """
164
        Encode the current dict instance in Base64 format
165
        using the given subformat and encoding.
166
        Encoder specific options can be passed using kwargs.
167
        Return the encoded string and optionally save it at 'filepath'.
168
        A ValueError is raised in case of failure.
169
        """
170
        kwargs['subformat'] = subformat
171
        kwargs['encoding'] = encoding
172
        return self._encode(self.dict(), 'base64', **kwargs)
173
174
    def to_csv(self, key='values', columns=None, columns_row=True, **kwargs):
175
        """
176
        Encode a list of dicts in the current dict instance in CSV format.
177
        Encoder specific options can be passed using kwargs:
178
        https://docs.python.org/3/library/csv.html
179
        Return the encoded string and optionally save it at 'filepath'.
180
        A ValueError is raised in case of failure.
181
        """
182
        kwargs['columns'] = columns
183
        kwargs['columns_row'] = columns_row
184
        return self._encode(self.dict()[key], 'csv', **kwargs)
185
186
    def to_ini(self, **kwargs):
187
        """
188
        Encode the current dict instance in INI format.
189
        Encoder specific options can be passed using kwargs:
190
        https://docs.python.org/3/library/configparser.html
191
        Return the encoded string and optionally save it at 'filepath'.
192
        A ValueError is raised in case of failure.
193
        """
194
        return self._encode(self.dict(), 'ini', **kwargs)
195
196
    def to_json(self, **kwargs):
197
        """
198
        Encode the current dict instance in JSON format.
199
        Encoder specific options can be passed using kwargs:
200
        https://docs.python.org/3/library/json.html
201
        Return the encoded string and optionally save it at 'filepath'.
202
        A ValueError is raised in case of failure.
203
        """
204
        return self._encode(self.dict(), 'json', **kwargs)
205
206
    def to_pickle(self, **kwargs):
207
        """
208
        Encode the current dict instance as pickle (encoded in Base64).
209
        The pickle protocol used by default is 2.
210
        Encoder specific options can be passed using kwargs:
211
        https://docs.python.org/3/library/pickle.html
212
        Return the encoded string and optionally save it at 'filepath'.
213
        A ValueError is raised in case of failure.
214
        """
215
        return self._encode(self.dict(), 'pickle', **kwargs)
216
217
    def to_plist(self, **kwargs):
218
        """
219
        Encode the current dict instance as p-list.
220
        Encoder specific options can be passed using kwargs:
221
        https://docs.python.org/3/library/plistlib.html
222
        Return the encoded string and optionally save it at 'filepath'.
223
        A ValueError is raised in case of failure.
224
        """
225
        return self._encode(self.dict(), 'plist', **kwargs)
226
227
    def to_query_string(self, **kwargs):
228
        """
229
        Encode the current dict instance in query-string format.
230
        Return the encoded string and optionally save it at 'filepath'.
231
        A ValueError is raised in case of failure.
232
        """
233
        return self._encode(self.dict(), 'query_string', **kwargs)
234
235
    def to_toml(self, **kwargs):
236
        """
237
        Encode the current dict instance in TOML format.
238
        Encoder specific options can be passed using kwargs:
239
        https://pypi.org/project/toml/
240
        Return the encoded string and optionally save it at 'filepath'.
241
        A ValueError is raised in case of failure.
242
        """
243
        return self._encode(self.dict(), 'toml', **kwargs)
244
245
    def to_xml(self, **kwargs):
246
        """
247
        Encode the current dict instance in XML format.
248
        Encoder specific options can be passed using kwargs:
249
        https://github.com/martinblech/xmltodict
250
        Return the encoded string and optionally save it at 'filepath'.
251
        A ValueError is raised in case of failure.
252
        """
253
        return self._encode(self.dict(), 'xml', **kwargs)
254
255
    def to_yaml(self, **kwargs):
256
        """
257
        Encode the current dict instance in YAML format.
258
        Encoder specific options can be passed using kwargs:
259
        https://pyyaml.org/wiki/PyYAMLDocumentation
260
        Return the encoded string and optionally save it at 'filepath'.
261
        A ValueError is raised in case of failure.
262
        """
263
        return self._encode(self.dict(), 'yaml', **kwargs)
264