def set(self, arguments): """Set key/value pairs from arguments :param list arguments: List of arguments with key=value pairs """ logmgr_flog() # count all valid and invalid xml files validfiles, invalidfiles = self.get_files_status(self.__xml) # split key and value args = [i.split("=") for i in arguments] # iter through all key and values for f in self.__files: if "error" in self.__xml[f]: print("[ {} ] {} -> {}".format(red("error"), f, red(self.__xml[f]['errorstr']))) else: for arg in args: try: key, value = arg if key == "languages": value = value.split(",") value = ",".join( self.remove_duplicate_langcodes(value)) log.debug( "[%s] Trying to set value for property " "%r to %r.", f, key, value) if self.__args.bugtracker: self.__xml[f]["handler"].set( {"bugtracker/" + key: value}) else: self.__xml[f]["handler"].set({key: value}) except ValueError: log.error('Invalid usage. ' 'Set values with the following format: ' 'property=value') sys.exit(ReturnCodes.E_INVALID_USAGE_KEYVAL) print("[ {} ] Set data for file {}.".format(green("ok"), f)) # save the changes for f in self.__files: if "error" not in self.__xml[f]: log.debug("[%s] Trying to save the changes.", f) self.__xml[f]["handler"].write() # print the statistics output print( "\nWrote {} valid XML file{} and skipped {} XML file{} due to errors." .format(green(validfiles), '' if validfiles == 1 else 's', red(invalidfiles), '' if invalidfiles == 1 else 's')) if invalidfiles > 0: sys.exit(ReturnCodes.E_SOME_FILES_WERE_INVALID)
def delete(self, arguments): """Delete a property :param list arguments: """ logmgr_flog() # statistics variables file_errors = 0 props_failed = 0 props_deleted = 0 # delete the properties for f in self.__files: if "error" in self.__xml[f]: print("[{}] {} -> {}".format(red(" error "), f, red(self.__xml[f]["errorstr"]))) file_errors += 1 else: failed_properties = list() for arg in arguments: cond = None prop = arg pos = arg.find("=") # look if there is condition if pos != -1: prop = arg[:pos] cond = arg[pos + 1:] if not self.__xml[f]["handler"].delete(prop, cond): failed_properties.append(arg) props_failed += 1 else: props_deleted += 1 if not failed_properties: print("[{}] {}".format(green(" ok "), f)) else: print("[{}] {} -> Couldn't delete these properties: {}". format(yellow(" info "), f, ", ".join(failed_properties))) # save changes for f in self.__files: if "error" not in self.__xml[f]: self.__xml[f]["handler"].write() # print statistics print("") print( "Deleted successfully {} propert{}, {} propert{} couldn't be deleted, and {} {} invalid." .format(green(props_deleted), 'ies' if props_deleted != 1 else 'y', yellow(props_failed), 'ies' if props_failed != 1 else 'y', red(file_errors), 'files were' if file_errors != 1 else 'file was'))
def set_attr(self, arguments): prop = self.__args.property attrs = self.__args.attributes if not prop: log.error("You must specify a property with -p!") sys.exit(ReturnCodes.E_INVALID_ARGUMENTS) if not attrs: log.error("You must specify at least one attribute with -a!") sys.exit(ReturnCodes.E_INVALID_ARGUMENTS) # count all valid and invalid xml files validfiles, invalidfiles = self.get_files_status(self.__xml) data = OrderedDict() for i in attrs: try: key, val = i.split("=") data[key] = val except ValueError: log.error( "The values of -a must have a key and a value, like: key=value or key=" ) sys.exit(ReturnCodes.E_INVALID_USAGE_KEYVAL) for f in self.__files: if "error" in self.__xml[f]: print("[{}] {} -> {}".format(red(" error "), f, red(self.__xml[f]["errorstr"]))) else: try: self.__xml[f]["handler"].set_attr(prop, data) self.__xml[f]["handler"].write() print("[{}] Set attributes for file {}.".format( green(" ok "), f)) except DMPropertyNotFound: print("[{}] Property {} was not found in {}.".format( red(" error "), yellow(prop), f)) # we must substract 1 of "validfiles" since XML files are valid even # if they don't have the given property. validfiles -= 1 invalidfiles += 1 # print the statistics output print( "\nWrote {} valid XML file{} and skipped {} XML file{} due to errors." .format(green(validfiles), '' if validfiles == 1 else 's', red(invalidfiles), '' if invalidfiles == 1 else 's')) if invalidfiles > 0: sys.exit(ReturnCodes.E_SOME_FILES_WERE_INVALID)
def del_attr(self, arguments): prop = self.__args.property attrs = self.__args.attributes if not prop: log.error("You must specify a property with -p!") sys.exit(ReturnCodes.E_INVALID_ARGUMENTS) if not attrs: log.error("You must specify at least one attribute with -a!") sys.exit(ReturnCodes.E_INVALID_ARGUMENTS) # count all valid and invalid xml files validfiles, invalidfiles = self.get_files_status(self.__xml) for f in self.__files: if "error" in self.__xml[f]: print("[{}] {} -> {}".format(red(" error "), f, red(self.__xml[f]["errorstr"]))) else: try: errors = self.__xml[f]["handler"].del_attr(prop, attrs) self.__xml[f]["handler"].write() if errors: print( "[{}] These attributes couldn't be deleted for {}: {}" .format(yellow(" notice "), f, ", ".join(errors))) else: print("[{}] Deleted attributes for file {}.".format( green(" ok "), f)) except DMPropertyNotFound: print("[{}] Property {} was not found in {}.".format( red(" error "), yellow(prop), f)) # we must substract 1 of "validfiles" since XML files are valid even # if they don't have the given property. validfiles -= 1 invalidfiles += 1 # print the statistics output print( "\nWrote {} valid XML file{} and skipped {} XML file{} due to errors." .format(green(validfiles), '' if validfiles == 1 else 's', red(invalidfiles), '' if invalidfiles == 1 else 's')) if invalidfiles > 0: sys.exit(ReturnCodes.E_SOME_FILES_WERE_INVALID)
def textrenderer(data, **kwargs): # pylint: disable=unused-argument """Normal text output :param list data: Filename with properties syntax: [(FILENAME, {PROPERTIES}), ...] :param dict kwargs: for further customizations :return: rendered output :rtype: str """ if data is None: return args = kwargs["args"] if args.action == "get": # print only the value of the given property if only one property and # only one file are given errors = data['errors'] data = data['data'] if len(data) == 1: if len(data[0][1]) == 1: for v in data[0][1]: if data[0][1][v] is not None: print(data[0][1][v]) return # if there are more than one file or one property for d in data: props = d[1] props = " ".join(["%s=%s" % (key, value) \ for key, value in props.items()]) if len(props): print("{} -> {}".format(d[0], props)) # print all errors if -q/--quiet is not set if errors and not args.quiet: print("") for i in errors: print("[{}] {} -> {}".format(red(" error "), i[0], i[1])) elif args.action == "get_attr": errors = data['errors'] data = data['data'] if data: for i in data: if data[i]: for prop in data[i]: if data[i][prop]: print("{}[{}] -> {}".format(i, prop, ", ".join(["%s=%s" % (key, value) \ for key, value in data[i][prop].items()])))
def analyze(self, arguments): # pylint:disable=unused-argument handlers = dict() # Set default query format try: qformat = self.args.config['analzye']['queryformat'] except KeyError: pass if self.args.queryformat: qformat = self.args.queryformat file_data = list() errors = list() ntfiledata = namedtuple("FileData", "file,out_formatted,data") validfiles, invalidfiles = self.get_files_status(self.__xml) for f in self.__files: if "error" in self.__xml[f]: errors.append("Error in '{}': {}".format( f, red(self.__xml[f]["errorstr"]))) else: try: analyzer = Analyzer(self.__xml[f]["handler"]) except DMInvalidXMLHandlerObject: log.critical("XML Handler object is None.") out = qformat[:] out = analyzer.replace_constants(out) fields = analyzer.extract_fields(out) data = analyzer.fetch_data(self.__args.filter, self.__args.sort, self.__args.default_output) if not self.__args.sort: # we can print all caught data here. If we have no data, we assume that the user # didn't want to see any data from the XML files and he just want to see the # output of the constants like {os.file} - https://github.com/openSUSE/docmanager/issues/93 if data: print(analyzer.format_output(out, data)) elif analyzer.filters_matched: print(analyzer.format_output(out, data)) else: file_data.append( ntfiledata(file=f, out_formatted=out, data=data)) if self.__args.sort: values = None if self.__args.sort == 'filename': values = sorted(file_data, key=lambda x: x.file) else: try: values = sorted(file_data, key=lambda x: int(x.data[self.__args.sort]) \ if x.data[self.__args.sort].isnumeric() \ else \ x.data[self.__args.sort]) except KeyError: log.error("Could not find key '{}' in -qf for sort.") if values: for i in values: print(analyzer.format_output(i.out_formatted, i.data)) if not self.__args.quiet: print("\nSuccessfully analyzed {} XML files.".format( green(validfiles))) if errors and not self.__args.quiet: print("Got {} errors in the analyzed files:\n".format( red(len(errors)))) for i in errors: print(i)
def init(self, arguments): logmgr_flog() _set = dict() props = list(DEFAULT_DM_PROPERTIES) # count all valid and invalid xml files validfiles, invalidfiles = self.get_files_status(self.__xml) # append bugtracker properties if needed if self.__args.with_bugtracker: for item in BT_ELEMENTLIST: props.append(item) # set default properties for item in props: rprop = item.replace("/", "_") if hasattr(self.__args, rprop) and \ getattr(self.__args, rprop) is not None: _set[item] = getattr(self.__args, rprop) # iter through all xml handlers and init its properties for f in self.__files: if "error" not in self.__xml[f]: xh = self.__xml[f]["handler"] log.info( "Trying to initialize the predefined DocManager " "properties for %r.", xh.filename) if xh.init_default_props(self.__args.force, self.__args.with_bugtracker) == 0: print("[{}] Initialized default " "properties for {!r}.".format( green(" ok "), xh.filename)) else: log.warn( "Could not initialize all properties for %r because " "there are already some properties in the XML file " "which would be overwritten after this operation has been " "finished. If you want to perform this operation and " "overwrite the existing properties, you can add the " "'--force' option to your command.", xh.filename) # set default values for the given properties for i in _set: ret = xh.get(i) if len(ret[i]) == 0 or self.__args.force: xh.set({i: str(_set[i])}) # if bugtracker options are provided, set default values for i in BT_ELEMENTLIST: rprop = i.replace("/", "_") if hasattr(self.__args, rprop) and \ getattr(self.__args, rprop) is not None and \ len(getattr(self.__args, rprop)) >= 1: xh.set({i: getattr(self.__args, rprop)}) else: print("[{}] Initialized default properties for {!r}: {}. ".format(\ red(" error "), f, red(self.__xml[f]["errorstr"]))) # save the changes if validfiles: for f in self.__files: if "error" not in self.__xml[f]: self.__xml[f]["handler"].write() # print the statistics print("\nInitialized successfully {} files. {} files failed.".format(\ green(validfiles), red(invalidfiles)))