from lxml import etree from collections import namedtuple RepoFlag = namedtuple('RepoFlag', 'setting repo arch') valid_flag_types = ('build', 'publish', 'useforbuild', 'debuginfo') class RepoFlags(): def __init__(self, flag_type=None, xml=None): self.flag_type = flag_type self.root = None if isinstance(xml, (str,)): try: self.import_xml(xml) except Exception: raise Exception('Failed to import xml') elif isinstance(xml, etree._Element): self.root = xml if self.flag_type is None and self.root is None: self.flag_type = 'build' self.__verify() def import_xml(self, xml): try: self.root = etree.fromstring(xml) except Exception as e: raise e def __verify(self): """ Make sure flag_type and xml data match. """ # if self.flag_type set, ensure it matches the tag of the root xml # element. If not matching, try to find the matching element within # the xml tree and set root to that. If not found, set root to a new # empty tree based on the flag_type if self.flag_type is not None: if self.flag_type not in valid_flag_types: raise ValueError('Invalid repo flag type %s' % self.flag_type) if self.root is None: self.root = etree.Element(self.flag_type) return if self.flag_type == self.root.tag: return element = self.root.find(self.flag_type) if element is not None: self.root = element return # If flag_type is not set, set it to the root element tag flag_type = self.root.tag if flag_type in valid_flag_types: return # if root element is not a valid repo flag type, search for the # first element that is a valid flag type and use it. for flag_type in valid_flag_types: element = self.root.find(flag_type) if element is not None: self.flag_type = flag_type self.root = element return self.flag_type = 'build' self.root = etree.Element(self.flag_type) @property def flags(self): for element in self.root: if element.tag not in ['enable', 'disable']: continue setting = element.tag repo = element.get('repository', None) arch = element.get('arch', None) yield(RepoFlag(setting=setting, repo=repo, arch=arch)) def set(self, setting, repo=None, arch=None): if setting not in ['enable', 'disable']: raise ValueError('Invalid Flag Setting %s' % setting) element = etree.Element(setting) if repo: element.set('repository', repo) if arch: element.set('arch', arch) self.root.append(element) def enable(self, repo=None, arch=None): self.set('enable', repo, arch) def disable(self, repo=None, arch=None): self.set('disable', repo, arch)