Total Complexity | 147 |
Total Lines | 626 |
Duplicated Lines | 5.75 % |
Changes | 10 | ||
Bugs | 0 | Features | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Actions 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 | # |
||
35 | class Actions(object): |
||
36 | """An Actions instance represents an action event |
||
37 | """ |
||
38 | |||
39 | def __init__(self, args): |
||
40 | """Initialize Actions class |
||
41 | |||
42 | :param argparse.Namespace args: result from argparse.parse_args |
||
43 | """ |
||
44 | logmgr_flog() |
||
45 | |||
46 | # set default variables |
||
47 | self.__files = args.files |
||
48 | self.__args = args |
||
49 | self.__xml = OrderedDict() |
||
50 | |||
51 | # set the default output format for 'alias' sub cmd to 'table' |
||
52 | if args.action == "alias": |
||
53 | args.format = "table" |
||
54 | |||
55 | if self.__files: |
||
56 | # temporary xml handler list |
||
57 | xml = list() |
||
58 | |||
59 | # start multiple processes for initialize all XML files |
||
60 | with ThreadPool(processes=self.__args.jobs) as pool: |
||
61 | for i in pool.map(self.init_xml_handlers, self.__files): |
||
62 | xml.append(i) |
||
63 | |||
64 | # build the self.__xml dict |
||
65 | for i in xml: |
||
66 | name = i["file"] |
||
67 | self.__xml[name] = dict() |
||
68 | |||
69 | for x in i: |
||
70 | if x is not "file": |
||
71 | self.__xml[name][x] = i[x] |
||
72 | |||
73 | # stop if we found an error and --stop-on-error is set |
||
74 | if self.__args.stop_on_error and "error" in self.__xml[name]: |
||
75 | log.error("{}: {}".format(name, self.__xml[name]["errorstr"])) |
||
76 | sys.exit(self.__xml[name]["error"]) |
||
77 | |||
78 | def init_xml_handlers(self, fname): |
||
79 | """ |
||
80 | Initializes an XmlHandler for a file. |
||
81 | |||
82 | :param string fname: The file name |
||
83 | """ |
||
84 | handler = None |
||
85 | |||
86 | try: |
||
87 | handler = { "file": fname, "handler": XmlHandler(fname, True) } |
||
88 | except (DMXmlParseError, DMInvalidXMLRootElement, DMFileNotFoundError, DMNotDocBook5File) as err: |
||
89 | handler = { "file": fname, "errorstr": err.errorstr, "error": err.error } |
||
90 | |||
91 | return handler |
||
92 | |||
93 | def parse(self): |
||
94 | logmgr_flog() |
||
95 | |||
96 | action = self.__args.action |
||
97 | if hasattr(self, action) and getattr(self, action) is not None: |
||
98 | log.debug("Action.__init__: %s", self.__args) |
||
99 | return getattr(self, action)(self.__args.properties) |
||
100 | else: |
||
101 | log.error("Method \"%s\" is not implemented.", action) |
||
102 | sys.exit(ReturnCodes.E_METHOD_NOT_IMPLEMENTED) |
||
103 | |||
104 | |||
105 | def init(self, arguments): |
||
106 | logmgr_flog() |
||
107 | |||
108 | _set = dict() |
||
109 | props = list(DEFAULT_DM_PROPERTIES) |
||
110 | |||
111 | # count all valid and invalid xml files |
||
112 | validfiles, invalidfiles = self.get_files_status(self.__xml) |
||
113 | |||
114 | # append bugtracker properties if needed |
||
115 | if self.__args.with_bugtracker: |
||
116 | for item in BT_ELEMENTLIST: |
||
117 | props.append(item) |
||
118 | |||
119 | # set default properties |
||
120 | for item in props: |
||
121 | rprop = item.replace("/", "_") |
||
122 | |||
123 | if hasattr(self.__args, rprop) and \ |
||
124 | getattr(self.__args, rprop) is not None: |
||
125 | _set[item] = getattr(self.__args, rprop) |
||
126 | |||
127 | # iter through all xml handlers and init its properties |
||
128 | for f in self.__files: |
||
129 | if "error" not in self.__xml[f]: |
||
130 | xh = self.__xml[f]["handler"] |
||
131 | |||
132 | log.info("Trying to initialize the predefined DocManager " |
||
133 | "properties for %r.", xh.filename) |
||
134 | |||
135 | if xh.init_default_props(self.__args.force, |
||
136 | self.__args.with_bugtracker) == 0: |
||
137 | print("[{}] Initialized default " |
||
138 | "properties for {!r}.".format(green(" ok "), |
||
139 | xh.filename)) |
||
140 | else: |
||
141 | log.warning("Could not initialize all properties for %r because " |
||
142 | "there are already some properties in the XML file " |
||
143 | "which would be overwritten after this operation has been " |
||
144 | "finished. If you want to perform this operation and " |
||
145 | "overwrite the existing properties, you can add the " |
||
146 | "'--force' option to your command.", xh.filename) |
||
147 | |||
148 | # set default values for the given properties |
||
149 | for i in _set: |
||
150 | ret = xh.get(i) |
||
151 | if len(ret[i]) == 0 or self.__args.force: |
||
152 | xh.set({ i: str(_set[i]) }) |
||
153 | |||
154 | # if bugtracker options are provided, set default values |
||
155 | for i in BT_ELEMENTLIST: |
||
156 | rprop = i.replace("/", "_") |
||
157 | |||
158 | if hasattr(self.__args, rprop) and \ |
||
159 | getattr(self.__args, rprop) is not None and \ |
||
160 | len(getattr(self.__args, rprop)) >= 1: |
||
161 | xh.set({ i: getattr(self.__args, rprop) }) |
||
162 | else: |
||
163 | print("[{}] Initialized default properties for {!r}: {}. ".format(\ |
||
164 | red(" error "), |
||
165 | f, |
||
166 | red(self.__xml[f]["errorstr"]))) |
||
167 | |||
168 | # save the changes |
||
169 | if validfiles: |
||
170 | for f in self.__files: |
||
171 | if "error" not in self.__xml[f]: |
||
172 | self.__xml[f]["handler"].write() |
||
173 | |||
174 | # print the statistics |
||
175 | print("\nInitialized successfully {} files. {} files failed.".format(\ |
||
176 | green(validfiles), red(invalidfiles))) |
||
177 | |||
178 | def set(self, arguments): |
||
179 | """Set key/value pairs from arguments |
||
180 | |||
181 | :param list arguments: List of arguments with key=value pairs |
||
182 | """ |
||
183 | logmgr_flog() |
||
184 | |||
185 | # count all valid and invalid xml files |
||
186 | validfiles, invalidfiles = self.get_files_status(self.__xml) |
||
187 | |||
188 | # split key and value |
||
189 | args = [i.split("=") for i in arguments] |
||
190 | |||
191 | # iter through all key and values |
||
192 | for f in self.__files: |
||
193 | if "error" in self.__xml[f]: |
||
194 | print("[ {} ] {} -> {}".format(red("error"), f, red(self.__xml[f]['errorstr']))) |
||
195 | else: |
||
196 | for arg in args: |
||
197 | try: |
||
198 | key, value = arg |
||
199 | |||
200 | if key == "languages": |
||
201 | value = value.split(",") |
||
202 | value = ",".join(self.remove_duplicate_langcodes(value)) |
||
203 | |||
204 | log.debug("[%s] Trying to set value for property " |
||
205 | "%r to %r.", f, key, value) |
||
206 | |||
207 | if self.__args.bugtracker: |
||
208 | self.__xml[f]["handler"].set({"bugtracker/" + key: value}) |
||
209 | else: |
||
210 | self.__xml[f]["handler"].set({key: value}) |
||
211 | except ValueError: |
||
212 | log.error('Invalid usage. ' |
||
213 | 'Set values with the following format: ' |
||
214 | 'property=value') |
||
215 | sys.exit(ReturnCodes.E_INVALID_USAGE_KEYVAL) |
||
216 | |||
217 | print("[ {} ] Set data for file {}.".format(green("ok"), f)) |
||
218 | |||
219 | # save the changes |
||
220 | for f in self.__files: |
||
221 | if "error" not in self.__xml[f]: |
||
222 | log.debug("[%s] Trying to save the changes.", f) |
||
223 | self.__xml[f]["handler"].write() |
||
224 | |||
225 | # print the statistics output |
||
226 | print("\nWrote {} valid XML file{} and skipped {} XML file{} due to errors.".format( |
||
227 | green(validfiles), |
||
228 | '' if validfiles == 1 else 's', |
||
229 | red(invalidfiles), |
||
230 | '' if invalidfiles == 1 else 's' |
||
231 | ) |
||
232 | ) |
||
233 | |||
234 | if invalidfiles > 0: |
||
235 | sys.exit(ReturnCodes.E_SOME_FILES_WERE_INVALID) |
||
236 | |||
237 | def set_attr(self, arguments): |
||
238 | prop = self.__args.property |
||
239 | attrs = self.__args.attributes |
||
240 | |||
241 | if not prop: |
||
242 | log.error("You must specify a property with -p!") |
||
243 | sys.exit(ReturnCodes.E_INVALID_ARGUMENTS) |
||
244 | |||
245 | if not attrs: |
||
246 | log.error("You must specify at least one attribute with -a!") |
||
247 | sys.exit(ReturnCodes.E_INVALID_ARGUMENTS) |
||
248 | |||
249 | # count all valid and invalid xml files |
||
250 | validfiles, invalidfiles = self.get_files_status(self.__xml) |
||
251 | |||
252 | data = OrderedDict() |
||
253 | for i in attrs: |
||
254 | try: |
||
255 | key, val = i.split("=") |
||
256 | data[key] = val |
||
257 | except ValueError: |
||
258 | log.error("The values of -a must have a key and a value, like: key=value or key=") |
||
259 | sys.exit(ReturnCodes.E_INVALID_USAGE_KEYVAL) |
||
260 | |||
261 | for f in self.__files: |
||
262 | View Code Duplication | if "error" in self.__xml[f]: |
|
|
|||
263 | print("[{}] {} -> {}".format(red(" error "), f, red(self.__xml[f]["errorstr"]))) |
||
264 | else: |
||
265 | try: |
||
266 | self.__xml[f]["handler"].set_attr(prop, data) |
||
267 | self.__xml[f]["handler"].write() |
||
268 | |||
269 | print("[{}] Set attributes for file {}.".format(green(" ok "), f)) |
||
270 | except DMPropertyNotFound: |
||
271 | print("[{}] Property {} was not found in {}.".format(red(" error "), yellow(prop), f)) |
||
272 | |||
273 | # we must substract 1 of "validfiles" since XML files are valid even |
||
274 | # if they don't have the given property. |
||
275 | validfiles -= 1 |
||
276 | invalidfiles += 1 |
||
277 | |||
278 | # print the statistics output |
||
279 | print("\nWrote {} valid XML file{} and skipped {} XML file{} due to errors.".format( |
||
280 | green(validfiles), |
||
281 | '' if validfiles == 1 else 's', |
||
282 | red(invalidfiles), |
||
283 | '' if invalidfiles == 1 else 's' |
||
284 | ) |
||
285 | ) |
||
286 | |||
287 | if invalidfiles > 0: |
||
288 | sys.exit(ReturnCodes.E_SOME_FILES_WERE_INVALID) |
||
289 | |||
290 | def del_attr(self, arguments): |
||
291 | prop = self.__args.property |
||
292 | attrs = self.__args.attributes |
||
293 | |||
294 | if not prop: |
||
295 | log.error("You must specify a property with -p!") |
||
296 | sys.exit(ReturnCodes.E_INVALID_ARGUMENTS) |
||
297 | |||
298 | if not attrs: |
||
299 | log.error("You must specify at least one attribute with -a!") |
||
300 | sys.exit(ReturnCodes.E_INVALID_ARGUMENTS) |
||
301 | |||
302 | # count all valid and invalid xml files |
||
303 | validfiles, invalidfiles = self.get_files_status(self.__xml) |
||
304 | |||
305 | for f in self.__files: |
||
306 | View Code Duplication | if "error" in self.__xml[f]: |
|
307 | print("[{}] {} -> {}".format(red(" error "), f, red(self.__xml[f]["errorstr"]))) |
||
308 | else: |
||
309 | try: |
||
310 | errors = self.__xml[f]["handler"].del_attr(prop, attrs) |
||
311 | self.__xml[f]["handler"].write() |
||
312 | |||
313 | if errors: |
||
314 | print("[{}] These attributes couldn't be deleted for {}: {}".format( |
||
315 | yellow(" notice "), f, ", ".join(errors) |
||
316 | )) |
||
317 | else: |
||
318 | print("[{}] Deleted attributes for file {}.".format(green(" ok "), f)) |
||
319 | |||
320 | except DMPropertyNotFound: |
||
321 | print("[{}] Property {} was not found in {}.".format(red(" error "), yellow(prop), f)) |
||
322 | |||
323 | # we must substract 1 of "validfiles" since XML files are valid even |
||
324 | # if they don't have the given property. |
||
325 | validfiles -= 1 |
||
326 | invalidfiles += 1 |
||
327 | |||
328 | # print the statistics output |
||
329 | print("\nWrote {} valid XML file{} and skipped {} XML file{} due to errors.".format( |
||
330 | green(validfiles), |
||
331 | '' if validfiles == 1 else 's', |
||
332 | red(invalidfiles), |
||
333 | '' if invalidfiles == 1 else 's' |
||
334 | ) |
||
335 | ) |
||
336 | |||
337 | if invalidfiles > 0: |
||
338 | sys.exit(ReturnCodes.E_SOME_FILES_WERE_INVALID) |
||
339 | |||
340 | def get_attr(self, arguments): |
||
341 | props = self.__args.properties |
||
342 | attrs = self.__args.attributes |
||
343 | |||
344 | data = dict(data=OrderedDict(),errors=None) |
||
345 | |||
346 | for f in self.__files: |
||
347 | data['data'][f] = self.__xml[f]["handler"].get_attr(props, attrs) |
||
348 | |||
349 | return data |
||
350 | |||
351 | def get(self, arguments): |
||
352 | """Lists all properties |
||
353 | |||
354 | :param list arguments: |
||
355 | :return: [(FILENAME, {PROPERTIES}), ...] |
||
356 | :rtype: list |
||
357 | """ |
||
358 | logmgr_flog() |
||
359 | |||
360 | output = list() |
||
361 | errors = list() |
||
362 | |||
363 | for f in self.__files: |
||
364 | if "error" in self.__xml[f]: |
||
365 | errors.append([f, self.__xml[f]['errorstr']]) |
||
366 | else: |
||
367 | output.append((f, self.__xml[f]["handler"].get(arguments))) |
||
368 | |||
369 | return {'data': output, 'errors': errors} |
||
370 | |||
371 | |||
372 | def delete(self, arguments): |
||
373 | """Delete a property |
||
374 | |||
375 | :param list arguments: |
||
376 | """ |
||
377 | logmgr_flog() |
||
378 | |||
379 | # statistics variables |
||
380 | file_errors = 0 |
||
381 | props_failed = 0 |
||
382 | props_deleted = 0 |
||
383 | |||
384 | # delete the properties |
||
385 | for f in self.__files: |
||
386 | if "error" in self.__xml[f]: |
||
387 | print("[{}] {} -> {}".format(red(" error "), f, red(self.__xml[f]["errorstr"]))) |
||
388 | file_errors += 1 |
||
389 | else: |
||
390 | failed_properties = list() |
||
391 | |||
392 | for arg in arguments: |
||
393 | cond = None |
||
394 | prop = arg |
||
395 | pos = arg.find("=") |
||
396 | |||
397 | # look if there is condition |
||
398 | if pos != -1: |
||
399 | prop = arg[:pos] |
||
400 | cond = arg[pos+1:] |
||
401 | |||
402 | if not self.__xml[f]["handler"].delete(prop, cond): |
||
403 | failed_properties.append(arg) |
||
404 | props_failed += 1 |
||
405 | else: |
||
406 | props_deleted += 1 |
||
407 | |||
408 | if not failed_properties: |
||
409 | print("[{}] {}".format(green(" ok "), f)) |
||
410 | else: |
||
411 | print("[{}] {} -> Couldn't delete these properties: {}".format( |
||
412 | yellow(" info "), f, ", ".join(failed_properties) |
||
413 | )) |
||
414 | |||
415 | # save changes |
||
416 | for f in self.__files: |
||
417 | if "error" not in self.__xml[f]: |
||
418 | self.__xml[f]["handler"].write() |
||
419 | |||
420 | # print statistics |
||
421 | print("") |
||
422 | print("Deleted successfully {} propert{}, {} propert{} couldn't be deleted, and {} {} invalid.".format( |
||
423 | green(props_deleted), 'ies' if props_deleted != 1 else 'y', |
||
424 | yellow(props_failed), 'ies' if props_failed != 1 else 'y', red(file_errors), |
||
425 | 'files were' if file_errors != 1 else 'file was' |
||
426 | )) |
||
427 | |||
428 | def analyze(self, arguments): # pylint:disable=unused-argument |
||
429 | handlers = dict() |
||
430 | |||
431 | # Set default query format |
||
432 | try: |
||
433 | qformat = self.args.config['analzye']['queryformat'] |
||
434 | except KeyError: |
||
435 | pass |
||
436 | |||
437 | if self.args.queryformat: |
||
438 | qformat = self.args.queryformat |
||
439 | |||
440 | file_data = list() |
||
441 | errors = list() |
||
442 | ntfiledata = namedtuple("FileData", "file,out_formatted,data") |
||
443 | validfiles, invalidfiles = self.get_files_status(self.__xml) |
||
444 | |||
445 | for f in self.__files: |
||
446 | if "error" in self.__xml[f]: |
||
447 | errors.append("Error in '{}': {}".format(f, red(self.__xml[f]["errorstr"]))) |
||
448 | else: |
||
449 | try: |
||
450 | analyzer = Analyzer(self.__xml[f]["handler"]) |
||
451 | except DMInvalidXMLHandlerObject: |
||
452 | log.critical("XML Handler object is None.") |
||
453 | |||
454 | out = qformat[:] |
||
455 | out = analyzer.replace_constants(out) |
||
456 | fields = analyzer.extract_fields(out) |
||
457 | data = analyzer.fetch_data(self.__args.filter, self.__args.sort, self.__args.default_output) |
||
458 | |||
459 | if not self.__args.sort: |
||
460 | # we can print all caught data here. If we have no data, we assume that the user |
||
461 | # didn't want to see any data from the XML files and he just want to see the |
||
462 | # output of the constants like {os.file} - https://github.com/openSUSE/docmanager/issues/93 |
||
463 | if data: |
||
464 | print(analyzer.format_output(out, data)) |
||
465 | elif analyzer.filters_matched: |
||
466 | print(analyzer.format_output(out, data)) |
||
467 | else: |
||
468 | file_data.append(ntfiledata(file=f, out_formatted=out, data=data)) |
||
469 | |||
470 | if self.__args.sort: |
||
471 | values = None |
||
472 | |||
473 | if self.__args.sort == 'filename': |
||
474 | values = sorted(file_data, key=lambda x: x.file) |
||
475 | else: |
||
476 | try: |
||
477 | values = sorted(file_data, key=lambda x: int(x.data[self.__args.sort]) \ |
||
478 | if x.data[self.__args.sort].isnumeric() \ |
||
479 | else \ |
||
480 | x.data[self.__args.sort]) |
||
481 | except KeyError: |
||
482 | log.error("Could not find key '{}' in -qf for sort.") |
||
483 | |||
484 | if values: |
||
485 | for i in values: |
||
486 | print(analyzer.format_output(i.out_formatted, i.data)) |
||
487 | |||
488 | if not self.__args.quiet: |
||
489 | print("\nSuccessfully analyzed {} XML files.".format(green(validfiles))) |
||
490 | |||
491 | if errors and not self.__args.quiet: |
||
492 | print("Got {} errors in the analyzed files:\n".format(red(len(errors)))) |
||
493 | for i in errors: |
||
494 | print(i) |
||
495 | |||
496 | def _readconfig(self, confname): |
||
497 | """Read the configuration file |
||
498 | |||
499 | :param str confname: name of configuration file |
||
500 | :return: ConfigParser object |
||
501 | """ |
||
502 | |||
503 | # exit if the config file is a directory |
||
504 | if os.path.isdir(confname): |
||
505 | log.error("File '{}' is a directory. Cannot write " |
||
506 | "into directories!".format(confname)) |
||
507 | sys.exit(ReturnCodes.E_FILE_IS_DIRECTORY) |
||
508 | |||
509 | # open the config file with the ConfigParser |
||
510 | conf = ConfigParser() |
||
511 | if not conf.read(confname): |
||
512 | if os.path.exists(confname): |
||
513 | log.error("Permission denied for file '{}'! " |
||
514 | "Maybe you need sudo rights?".format(confname)) |
||
515 | sys.exit(ReturnCodes.E_PERMISSION_DENIED) |
||
516 | return conf |
||
517 | |||
518 | def config(self, values): # pylint:disable=unused-argument |
||
519 | if not self.__args.system and not self.__args.user and not self.__args.repo and not self.__args.own: |
||
520 | log.error("No config file specified. Please choice between either '--system', '--user', '--repo', or '--own'.") |
||
521 | sys.exit(ReturnCodes.E_CONFIGCMD_NO_METHOD_SPECIFIED) |
||
522 | |||
523 | prop = self.__args.property |
||
524 | value = self.__args.value |
||
525 | |||
526 | # search for the section, the property and the value |
||
527 | pos = prop.find(".") |
||
528 | if pos == -1: |
||
529 | log.error("Invalid property syntax. Use: section.property") |
||
530 | sys.exit(ReturnCodes.E_INVALID_CONFIG_PROPERTY_SYNTAX) |
||
531 | |||
532 | section = prop[:pos] |
||
533 | prop = prop[pos+1:] |
||
534 | |||
535 | confname = None |
||
536 | |||
537 | # determine config file |
||
538 | if self.__args.system: |
||
539 | confname = GLOBAL_CONFIG[0] |
||
540 | elif self.__args.user: |
||
541 | confname = USER_CONFIG |
||
542 | elif self.__args.repo: |
||
543 | confname = GIT_CONFIG |
||
544 | elif self.__args.own: |
||
545 | confname = self.__args.own |
||
546 | |||
547 | # open the config file with the ConfigParser |
||
548 | conf = self._readconfig(confname) |
||
549 | |||
550 | # handle the 'get' method |
||
551 | if value is None: |
||
552 | if conf.has_section(section): |
||
553 | try: |
||
554 | print(conf.get(section, prop)) |
||
555 | except NoOptionError: |
||
556 | pass |
||
557 | |||
558 | sys.exit(ReturnCodes.E_OK) |
||
559 | |||
560 | # add the section if its not available |
||
561 | if not conf.has_section(section): |
||
562 | conf.add_section(section) |
||
563 | |||
564 | # set the property |
||
565 | conf.set(section, prop, value) |
||
566 | |||
567 | # save the changes |
||
568 | try: |
||
569 | if not os.path.exists(confname): |
||
570 | # 'x' for creating and writing to a new file |
||
571 | conf.write(open(confname, 'x')) # pylint:disable=bad-open-mode |
||
572 | else: |
||
573 | conf.write(open(confname, 'w')) |
||
574 | except PermissionError: # pylint:disable=undefined-variable |
||
575 | log.error("Permission denied for file '{}'! " |
||
576 | "Maybe you need sudo rights?".format(confname)) |
||
577 | sys.exit(ReturnCodes.E_PERMISSION_DENIED) |
||
578 | |||
579 | def alias(self, values): |
||
580 | action = self.__args.alias_action |
||
581 | alias = self.__args.alias |
||
582 | value = self.__args.command |
||
583 | m = { 0: None, 1: GLOBAL_CONFIG[0], 2: USER_CONFIG, 3: GIT_CONFIG } |
||
584 | configname = m.get(self.__args.method, self.__args.own) |
||
585 | save = False |
||
586 | |||
587 | if action != 'list': |
||
588 | if alias is None and value is None: |
||
589 | log.error("You have to provide an alias name for method '{}'.".format(action)) |
||
590 | sys.exit(ReturnCodes.E_INVALID_ARGUMENTS) |
||
591 | |||
592 | if not value: |
||
593 | value = "" |
||
594 | |||
595 | # parse the config file |
||
596 | conf = self._readconfig(configname) |
||
597 | |||
598 | # add alias section if it's not found |
||
599 | if not conf.has_section("alias"): |
||
600 | conf.add_section("alias") |
||
601 | |||
602 | # handle actions |
||
603 | if action == "set": |
||
604 | conf.set("alias", alias, value) |
||
605 | save = True |
||
606 | elif action == "get": |
||
607 | try: |
||
608 | print(conf.get("alias", alias)) |
||
609 | except NoOptionError: |
||
610 | pass |
||
611 | elif action == "del": |
||
612 | save = True |
||
613 | conf.remove_option("alias", alias) |
||
614 | elif action == "list": |
||
615 | data = dict() |
||
616 | data["configfile"] = configname |
||
617 | data["aliases"] = conf['alias'] |
||
618 | |||
619 | return data |
||
620 | |||
621 | # save the changes |
||
622 | if save: |
||
623 | try: |
||
624 | if not os.path.exists(configname): |
||
625 | log.error("The config file does not exists.") |
||
626 | sys.exit(ReturnCodes.E_FILE_NOT_FOUND) |
||
627 | |||
628 | conf.write(open(configname, 'w')) |
||
629 | except PermissionError: |
||
630 | log.error("Permission denied for file '{}'! " |
||
631 | "Maybe you need sudo rights?".format(configname)) |
||
632 | sys.exit(ReturnCodes.E_PERMISSION_DENIED) |
||
633 | |||
634 | def remove_duplicate_langcodes(self, values): |
||
635 | new_list = [] |
||
636 | for i in values: |
||
637 | if i not in new_list: |
||
638 | new_list.append(i) |
||
639 | |||
640 | return new_list |
||
641 | |||
642 | def get_files_status(self, handlers): |
||
643 | """Count all valid and invalid XML files |
||
644 | |||
645 | :param dict handlers: The self.__xml object with all XML handlers |
||
646 | """ |
||
647 | validfiles = 0 |
||
648 | invalidfiles = 0 |
||
649 | |||
650 | for i in self.__files: |
||
651 | if "error" in handlers[i]: |
||
652 | invalidfiles += 1 |
||
653 | else: |
||
654 | validfiles += 1 |
||
655 | |||
656 | return [validfiles, invalidfiles] |
||
657 | |||
658 | @property |
||
659 | def args(self): |
||
660 | return self.__args |
||
661 |