| 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 |