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