tablerenderer()   F
last analyzed

Complexity

Conditions 16

Size

Total Lines 64

Duplication

Lines 25
Ratio 39.06 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 16
c 4
b 0
f 0
dl 25
loc 64
rs 2.8197

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like tablerenderer() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#
2
# Copyright (c) 2015 SUSE Linux GmbH
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of version 3 of the GNU General Public License as
6
# published by the Free Software Foundation.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, contact SUSE LLC.
15
#
16
# To contact SUSE about this file by physical or electronic mail,
17
# you may find current contact information at www.suse.com
18
19
import json
20
import sys
21
from collections import OrderedDict
22
from lxml import etree
23
from prettytable import PrettyTable
24
from docmanager.core import ReturnCodes
25
from docmanager.shellcolors import red,green
26
27
def textrenderer(data, **kwargs): # pylint: disable=unused-argument
28
    """Normal text output
29
30
    :param list data: Filename with properties
31
                      syntax: [(FILENAME, {PROPERTIES}), ...]
32
    :param dict kwargs: for further customizations
33
    :return: rendered output
34
    :rtype: str
35
    """
36
37
    if data is None:
38
        return
39
40
    args = kwargs["args"]
41
42
    if args.action == "get":
43
        # print only the value of the given property if only one property and
44
        # only one file are given
45
        errors = data['errors']
46
        data = data['data']
47
48
        if len(data) == 1:
49
            if len(data[0][1]) == 1:
50
                for v in data[0][1]:
51
                    if data[0][1][v] is not None:
52
                        print(data[0][1][v])
53
                    return
54
55
        # if there are more than one file or one property
56
        for d in data:
57
            props = d[1]
58
            props = " ".join(["%s=%s" % (key, value) \
59
                              for key, value in props.items()])
60
            if len(props):
61
                print("{} -> {}".format(d[0], props))
62
63
        # print all errors if -q/--quiet is not set
64
        if errors and not args.quiet:
65
            print("")
66
67
            for i in errors:
68
                print("[{}] {} -> {}".format(red(" error "), i[0], i[1]))
69
    elif args.action == "get_attr":
70
        errors = data['errors']
71
        data = data['data']
72
73
        if data:
74
            for i in data:
75
                if data[i]:
76
                    for prop in data[i]:
77
                        if data[i][prop]:
78
                            print("{}[{}] -> {}".format(i, prop, ", ".join(["%s=%s" % (key, value) \
79
                                                          for key, value in data[i][prop].items()])))
80
81
def tablerenderer(data, **kwargs): # pylint: disable=unused-argument
82
    """Output as table
83
84
    :param list data: Filename with properties
85
                      syntax: [(FILENAME, {PROPERTIES}), ...]
86
    :param dict kwargs: for further customizations
87
    :return: rendered output
88
    :rtype: str
89
    """
90
    if data is None:
91
        return
92
93
    args = kwargs["args"]
94 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
95
    if args.action == "alias":
96
        if len(data['aliases']) == 0:
97
            print("There are no aliases in config file: {}".format(data["configfile"]))
98
        else:
99
            table = PrettyTable(["Alias", "Command"])
100
            table.align["Alias"] = "l" # left align
101
            table.align["Command"] = "l" # left align
102
103
            for i in data['aliases']:
104
                table.add_row([i, data['aliases'][i]])
105
106
            print(table)
107
    elif args.action == "get":
108 View Code Duplication
        index = 0
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
109
        for i in data['data']:
110
            if len(i[1]):
111
                filename = i[0]
112
                print("File: {}".format(filename))
113
                table = PrettyTable(["Property", "Value"])
114
                table.align["Property"] = "l" # left align
115
                table.align["Value"] = "l" # left align
116
117
                for prop in i[1]:
118
                    value = i[1][prop]
119
                    table.add_row([prop, value])
120
121
                print(table)
122
                if (len(data)-1) is not index:
123
                    print("")
124
125
            index += 1
126
    elif args.action == "get_attr":
127
        if data['data']:
128
            # file names
129
            for f in data['data']:
130
                if data['data'][f]:
131
                    print("File: {}".format(f))
132
133
                    table = PrettyTable(["Property", "Attribute", "Value"])
134
                    table.align["Property"] = "1"
135
                    table.align["Attribute"] = "1"
136
                    table.align["Value"] = "1"
137
138
                    # properties
139
                    for prop in data['data'][f]:
140
                        # attributes
141
                        for i in data['data'][f][prop]:
142
                            table.add_row([prop, i, data['data'][f][prop][i]])
143
144
                    print(table)
145
146
147
def jsonrenderer(data, **kwargs): # pylint: disable=unused-argument
148
    """Output as JSON
149
150
    :param list data: Filename with properties
151
                      syntax: [(FILENAME, {PROPERTIES}), ...]
152
    :param dict kwargs: for further customizations
153
    :return: rendered output
154
    :rtype: str
155
    """
156
157
    args = kwargs["args"]
158
159
    if args.action == "alias":
160
        json_out = OrderedDict()
161
        for i in data['aliases'].keys():
162
            json_out[i] = {}
163
            json_out[i] = data['aliases'][i]
164
165
        print(json.dumps(json_out))
166
    elif args.action == "get":
167
        json_out = OrderedDict()
168
        for i in data['data']:
169
            json_out[i[0]] = {}
170
            json_out[i[0]] = i[1]
171
172
        print(json.dumps(json_out))
173
    elif args.action == "get_attr":
174
        json_out = OrderedDict()
175
        data = data['data']
176
177
        print(json.dumps(data))
178
179
def xmlrenderer(data, **kwargs): # pylint: disable=unused-argument
180
    """Output as XML
181
182
    :param list data: Filename with properties
183
                      syntax: [(FILENAME, {PROPERTIES}), ...]
184
    :param dict kwargs: for further customizations
185
    :return: rendered output
186
    :rtype: str
187
    """
188
189
    root = etree.Element("docmanager")
190
    tree = root.getroottree()
191
192
    args = kwargs["args"]
193
    index = 0
194
195
    if args.action == "alias":
196
        aliaseselem = etree.Element("aliases")
197
        root.append(aliaseselem)
198
199
        for name in data['aliases'].keys():
200
            value = data['aliases'][name]
201
202
            root[0].append(etree.Element("alias"))
203
204
            child = root[0][index]
205
            child.set("name", name)
206
207
            child.text = value
208
209
            index += 1
210
211
    elif args.action == "get":
212
        fileselem = etree.Element("files")
213
        root.append(fileselem)
214
215
        for i in data['data']:
216
            if len(i[1]):
217
                filename = i[0]
218
219
                root[0].append(etree.Element("file"))
220
221
                child = root[0][index]
222
                child.set("name", filename)
223
224
                for x in i[1]:
225
                    prop = x
226
                    value = i[1][x]
227
228
                    elem = etree.Element("property")
229
                    elem.set("name", prop)
230
                    elem.text = value
231
232
                    child.append(elem)
233
234
                index += 1
235
236
    elif args.action == "get_attr":
237
        """
238
        Output structure:
239
        <!DOCTYPE docmanager>
240
        <docmanager>
241
          <files>
242
            <file name="example.xml">
243
              <property name="priority/test/hello">
244
                <attribute name="someattribute">Hello</attribute>
245
                <attribute name="attr2">Hallo</attribute>
246
              </property>
247
              <property name="status">
248
                <attribute name="attr3">Hi</attribute>
249
              </property>
250
            </file>
251
          </files>
252
        </docmanager>
253
        """
254
255
        fileselem = etree.Element("files")
256
        root.append(fileselem)
257
258
        if data['data']:
259
            index = 0
260
261
            for i in data['data']:
262
                filename = i
263
                root[0].append(etree.Element("file"))
264
265
                child = root[0][index]
266
                child.set("name", filename)
267
268
                for prop in data['data'][i]:
269
                    propelem = etree.Element("property")
270
                    child.append(propelem)
271
                    propelem.set("name", prop)
272
273
                    for key, value in data['data'][i][prop].items():
274
                        elem = etree.Element("attribute")
275
                        elem.set("name", key)
276
                        elem.text = value
277
278
                        propelem.append(elem)
279
280
                    index += 1
281
282
    print(etree.tostring(tree,
283
                         encoding="unicode",
284
                         pretty_print=True,
285
                         doctype="<!DOCTYPE docmanager>"))
286
287
288
DEFAULTRENDERER = textrenderer
289
290
def getrenderer(fmt):
291
    """Returns the renderer for a specific format
292
293
    :param str fmt: format ('text', 'table', 'json', or 'default')
294
    :return: function of renderer
295
    :rtype: function
296
    """
297
    # Available renderers
298
    renderer = {
299
        'default': textrenderer,
300
        'text':    textrenderer,
301
        'table':   tablerenderer,
302
        'json':    jsonrenderer,
303
        'xml':     xmlrenderer,
304
    }
305
306
    return renderer.get(fmt, DEFAULTRENDERER)
307
308
309
def print_stats(validfiles, invalidfiles):
310
    """Print statistics how many files were valid/invalid, do a sys.exit
311
    if there were invalid files.
312
313
    :param int validfiles: The number of valid files
314
    :param int invalidfiles: The number of invalid files
315
    """
316
317
    message = "\n"
318
    if validfiles > 0:
319
        message += "Wrote {} valid XML file{}. ".format(
320
            green(validfiles),
321
            '' if validfiles == 1 else 's'
322
            )
323
    if invalidfiles > 0:
324
        message += "Skipped {} XML file{} due to errors.".format(
325
            red(invalidfiles),
326
            '' if invalidfiles == 1 else 's'
327
            )
328
329
    print(message)
330
331
    if invalidfiles > 0:
332
        sys.exit(ReturnCodes.E_SOME_FILES_WERE_INVALID)
333