Completed
Push — master ( b41131...fd0db2 )
by Charles
10s
created

FileDumper.__dump_csv()   A

Complexity

Conditions 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
dl 0
loc 19
ccs 8
cts 8
cp 1
crap 4
rs 9.2
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2 1
'''
3
Data dumper to files with several format
4
'''
5 1
from __future__ import unicode_literals
6
7 1
import json
8 1
from builtins import open
1 ignored issue
show
Bug Best Practice introduced by
This seems to re-define the built-in open.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
9
10 1
import xmltodict
11 1
import yaml
12 1
from backports import configparser, csv
0 ignored issues
show
Configuration introduced by
The import backports could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
13
14 1
import git_app_version.helper.tools as tools
15
16
17 1
class FileDumper(object):
18
    '''
19
    Main dumper
20
    '''
21
22 1
    def dump(self,
0 ignored issues
show
best-practice introduced by
Too many arguments (9/5)
Loading history...
23
             data=None,
24
             fileformat='json',
25
             target=None,
26
             cwd=None,
27
             namespace='',
28
             csv_delimiter=',',
29
             csv_quote='"',
30
             csv_eol='lf'):
31
        '''
32
        Agnostic main dump function
33
        '''
34
35 1
        target = tools.create_parent_dirs(target, cwd)
36 1
        if fileformat == 'yaml' or fileformat == 'yml':
37 1
            return self.__dump_yaml(data, target, namespace)
38 1
        elif fileformat == 'xml':
39 1
            return self.__dump_xml(data, target, namespace)
40 1
        elif fileformat == 'ini':
41 1
            return self.__dump_ini(data, target, namespace)
42 1
        elif fileformat == 'sh':
43 1
            return self.__dump_sh(data, target)
44 1
        elif fileformat == 'csv':
45 1
            return self.__dump_csv(data, target, delimiter=csv_delimiter,
46
                                   quotechar=csv_quote, eol=csv_eol)
47
        else:
48 1
            return self.__dump_json(data, target, namespace)
49
50 1
    def __create_infos_to_dump(self, infos, namespace=None):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
51
        '''
52
        reorganize data with a namespace if necessary
53
        '''
54
55 1
        to_dump = infos
56 1
        if namespace is not None and namespace != '':
57 1
            namespaces = namespace.split('.')
58 1
            namespaces.reverse()
59 1
            for name in namespaces:
60 1
                to_dump = {name: to_dump}
61
62 1
        return to_dump
63
64 1
    def __dump_sh(self, data, target):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
65
        '''
66
        dump to Shell variables file
67
        '''
68
69 1
        target = target + '.sh'
70
71 1
        with open(target, 'w', encoding='utf-8') as fpt:
72 1
            for key, val in data.items():
73 1
                fpt.write("{}=\"{}\"\n".format(key, tools.flatten(val)))
74
75 1
        return target
76
77 1
    def __dump_csv(self, data, target, delimiter=',', quotechar='"', eol='lf'):
0 ignored issues
show
best-practice introduced by
Too many arguments (6/5)
Loading history...
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
78
        '''
79
        dump to CSV file (comma separated values)
80
        '''
81
82 1
        target = target + '.csv'
83
84 1
        eol = '\r\n' if eol == 'crlf' or eol == '\r\n' else '\n'
85
86 1
        with open(target, 'w', encoding='utf-8') as fpt:
87 1
            writer = csv.writer(fpt,
88
                                delimiter=delimiter,
89
                                lineterminator=eol,
90
                                quotechar=quotechar,
91
                                quoting=csv.QUOTE_MINIMAL)
92 1
            for key, val in data.items():
93 1
                writer.writerow((key, tools.flatten(val)))
94
95 1
        return target
96
97 1
    def __dump_ini(self, data, target, namespace=None):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
98
        '''
99
        dump to INI file
100
        '''
101
102 1
        target = target + '.ini'
103
104 1
        if namespace is None or namespace == '':
105 1
            namespace = 'app_version'
106
107 1
        ini = configparser.RawConfigParser()
108 1
        ini.add_section(namespace)
109
110 1
        for key, val in data.items():
111 1
            ini.set(namespace, key, tools.flatten(val))
112
113 1
        with open(target, 'w', encoding='utf-8') as fpt:
114 1
            ini.write(fpt)
115
116 1
        return target
117
118 1
    def __dump_xml(self, data, target, namespace=None):
119
        '''
120
        dump to XML file
121
        '''
122
123 1
        target = target + '.xml'
124 1
        if namespace is None or namespace == '':
125 1
            namespace = 'app_version'
126
127 1
        with open(target, 'w', encoding='utf-8') as fpt:
128 1
            xml = xmltodict.unparse(
129
                self.__create_infos_to_dump(data, namespace),
130
                encoding='utf-8',
131
                pretty=True,
132
                indent='  ')
133
134 1
            fpt.write(xml)
135
136 1
            return target
137
138 1
    def __dump_json(self, data, target, namespace=None):
139
        '''
140
        dump to JSON file
141
        '''
142
143 1
        target = target + '.json'
144
145 1
        data1 = self.__create_infos_to_dump(data, namespace)
146
147 1
        with open(target, 'w', encoding='utf-8') as fpt:
148 1
            fpt.write(json.dumps(data1, indent=2, ensure_ascii=False))
149
150 1
        return target
151
152 1
    def __dump_yaml(self, data, target, namespace=None):
153
        '''
154
        dump to YAML file
155
        '''
156
157 1
        target = target + '.yml'
158
159 1
        with open(target, 'w', encoding='utf-8') as fpt:
160 1
            if not data:
161 1
                fpt.write("---\n")
162
            else:
163 1
                yaml.safe_dump(
164
                    self.__create_infos_to_dump(data, namespace),
165
                    fpt,
166
                    default_flow_style=False,
167
                    explicit_start=True,
168
                    allow_unicode=True,
169
                    # force quoting
170
                    # to prevent abbrev_commit to be read as a float
171
                    default_style='\''
172
                )
173
174
        return target
175