Completed
Push — master ( ad01fe...01a50b )
by Fabio
03:50
created

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

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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