コード例 #1
0
def create_userconfig():
    """Copies template for user config to USER_CONFIG
       If user config already exists, do nothing

     :raise: FileNotFoundError
    """
    if os.path.exists(USER_CONFIG):
        return

    import shutil

    tmpldir = os.path.join(os.path.dirname(__file__), "template")
    cfgtmpl = os.path.join(tmpldir, "config")

    # From http://stackoverflow.com/a/600612
    try:
        os.makedirs(os.path.dirname(USER_CONFIG))
        log.debug("UserConfig: Created directory for %s", USER_CONFIG)
    except OSError as err:
        import errno
        if not (err.errno == errno.EEXIST and os.path.isdir(tmpldir)):
            raise

    shutil.copyfile(cfgtmpl, USER_CONFIG)
    log.debug("UserConfig: Copied template %s to %s", cfgtmpl, USER_CONFIG)
コード例 #2
0
    def indent_dm(self):
        """Indents only dm:docmanager element and its children"""
        logmgr_flog()

        dmindent='    '
        dm = self.__tree.find("//dm:docmanager",
                              namespaces=NS)
        log.debug("dm is %s", dm)
        if dm is None:
            return
        log.debug("-----")
        info = dm.getparent() #.getprevious()
        log.info("info: %s", info)
        prev = info.getprevious()
        log.info("prev: %s", prev)
        parent = info.getparent()
        log.info("parent of info: %s", parent)
        log.info("child of info: %s", info.getchildren())

        if info.tail is None:
            info.tail = ""

        infoindent = "".join(info.tail.split('\n'))
        prev = dm.getprevious()
        #log.info("prev: %s", prev)
        if prev is not None:
            log.info("prev: %s", prev)
            prev.tail = '\n' + infoindent
        indent=self.get_indentation(dm.getprevious())
        dm.text = '\n' + indent + '    '
        dm.tail = '\n' + infoindent
        for node in dm.iterchildren():
            i = dmindent if node.getnext() is not None else ''
            node.tail = '\n' + indent + i
コード例 #3
0
    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)
コード例 #4
0
    def parse(self):
        logmgr_flog()

        action = self.__args.action
        if hasattr(self, action) and getattr(self, action) is not None:
            log.debug("Action.__init__: %s", self.__args)
            return getattr(self, action)(self.__args.properties)
        else:
            log.error("Method \"%s\" is not implemented.", action)
            sys.exit(ReturnCodes.E_METHOD_NOT_IMPLEMENTED)
コード例 #5
0
    def create_group(self):
        """Creates the docmanager group element"""
        logmgr_flog()

        #search the info-element if not exists raise an error
        info = self.__tree.find("//d:info", namespaces=NS)
        # TODO: We need to check for a --force option
        if info is None:
            log.debug("No <info> element found!")
            pos = findinfo_pos(self.__root)
            log.debug("Using position %d", pos)
            info = etree.Element("{%s}info" % NS["d"])
            info.tail = '\n'
            info.text = '\n'
            self.__root.insert(pos, info)

            log.debug("Adding <info> element in '%s'", self.filename)

        log.debug("Adding <dm:docmanager> to <info>")
        # dm = etree.Element("{%s}docmanager" % NS["dm"])
        # self.__docmanager = info.insert(0, dm)
        self.__docmanager = etree.SubElement(info,
                                             "{{{dm}}}docmanager".format(**NS),
                                             nsmap={'dm': NS['dm']},
                                            )
コード例 #6
0
    def __init__(self, filename, stoponerror=True):
        """Initializes the XmlHandler class

        :param str filename: filename of XML file
        """
        logmgr_flog()
        log.debug("Initialized a new XML Handler for file %r.", filename)

        # general
        self._filename = ""
        self._buffer = None # StringIO

        # file util
        self._fileutil = FileUtil(filename)

        # prolog
        self._offset = 0
        self._header = ""
        self._root = ""
        self.roottag = ""

        # parser
        self.__xmlparser = None
        self.invalidfile = False
        self.fileerror = ""
        self.xmlerrorstring = ""
        self.stoponerror = stoponerror

        # lxml
        self.__tree = None
        self.__root = None
        self.__docmanager = None

        # load the file into a StringIO buffer
        self._filename = filename
        self._buffer = ensurefileobj(self._filename)

        # log
        self.xmllogerrorstring = ""

        # parse the given file with lxml
        self.parse()
コード例 #7
0
    def write(self):
        """Write XML tree to original filename"""
        logmgr_flog()

        # Only indent docmanager child elements
        self.indent_dm()

        log.debug("root: %s", repr(self._root))
        with open(self._filename, 'w') as f:
            info = self.__root.find("d:info", namespaces=NS)

            xml_indent(info, 2)
            content = recover_entities(etree.tostring(self.__tree, \
                           encoding='unicode', \
                           # doctype=self._header.rstrip())
                      ))
            # self._offset, self._header, self._root, self._roottag
            starttag = compilestarttag(self._roottag)
            content = starttag.sub(lambda _: self._root.rstrip(), content, 1)

            # log.debug("content: %s", repr(content))
            f.write(self._header.rstrip()+"\n" + content)
コード例 #8
0
def docmanagerconfig(cfgfiles=None, include_etc=True):
    """Read DocManager configuration files. The following files are
       searched for and its configuration is merged together
       (in this order, from lowest to highest):

       * /etc/docmanager/config
       * $XDG_CONFIG_HOME/docmanager/docmanager.config if not found, falls back
         to ~/.config/docmanager/docmanager.config
       * GIT_REPO_DIR/.git/docmanager.conf
         (GIT_REPO_DIR is retrieved by the command
         `git rev-parse --show-toplevel`)
       * DOCMANAGER_GIT_REPO/etc/config

      See the XDG Base Directory Specification:
      http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html

      :param list cfgfiles: your own list of configfiles
      :param bool include_etc: Should the develop(!) 'etc/' directory included?
                               Only useful for development
      :return: merged configuration object
      :rtype: configparser.ConfigParser

    """
    # Start with the global ones
    configfiles = GLOBAL_CONFIG[:]

    if cfgfiles is None:
        # We need to assemble our configuration file list
        #
        # Append user config; env variable XDG_CONFIG_HOME is used if set
        configfiles.append(USER_CONFIG)

        # Append config when a .git repo is found
        gitcfg = get_git_repo_config()
        if gitcfg:
            configfiles.append(gitcfg)
    else:
        log.debug("Using own config file %s", cfgfiles)
        # In case the user passes its own config file list, use it but
        # take care, it's a list:
        if isinstance(cfgfiles, str):
            configfiles = [cfgfiles]
        else:
            configfiles = cfgfiles

    # Support pyvenv virtual environments; add it as a last item
    #
    # See http://stackoverflow.com/a/1883251
    if (cfgfiles is None) and include_etc and hasattr(sys, 'base_prefix'):
        #dd = os.path.dirname(__file__)
        #cc = os.path.join(dd, BASECONFIG_NAME)
        #configfiles.append(cc)
        #log.debug("Running inside a virtual env, using %s", cc)
        #
        # When code with __file__ is packed inside a zipfile, it can no longer
        # assume that __file__ or __path__ contain filenames or directory
        # names, and so it will fail (see also PEP 302)
        #
        # As such:
        # 1. First try to use pkg_resources from setuptools (which is installed
        #    anyway in a virtual Python environment)
        # 2. If that doesn't work, fallback to the __file__ method
        #
        # Source:
        # http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources
        #
        try:
            from pkg_resources import resource_filename
            cc = resource_filename(__name__, BASECONFIG_NAME)
            configfiles.append(cc)
        except ImportError:
            # Use fallback method
            dd = os.path.dirname(__file__)
            cc = os.path.join(dd, BASECONFIG_NAME)
            configfiles.append(cc)
        log.info("Running inside a virtual env, using %r", configfiles[-1])

    config = ConfigParser()
    x = config.read(configfiles)

    if not x:

        raise DMConfigFileNotFound(configfiles)

    # Save state of configuration files
    config.configfiles = configfiles
    config.usedconfigfile = x
    log.debug("All configfiles %s", configfiles)
    log.debug("Used config file: %s", x)

    return config
コード例 #9
0
    def parse(self):
        """This function parses the whole XML file
        """
        logmgr_flog()

        # find the prolog of the XML file (everything before the start tag)
        try:
            prolog = findprolog(self._buffer)
        except SAXParseException as err:
            self.invalidfile = True
            self.fileerror = "<{}:{}> {} in {!r}.".format(\
                                            err.getLineNumber(), \
                                            err.getColumnNumber(), \
                                            err.getMessage(), \
                                            self.filename,)

            if self.stoponerror:
                raise DMXmlParseError(self.fileerror, ReturnCodes.E_XML_PARSE_ERROR)

        if not self.invalidfile:
            # save prolog details
            self._offset, self._header, self._root, self._roottag = prolog['offset'], \
                prolog['header'], \
                prolog['root'], \
                prolog['roottag']

            # replace any entities
            self.replace_entities()

            # register namespace
            # etree.register_namespace("dm", "{dm}".format(**NS))
            self.__xmlparser = etree.XMLParser(remove_blank_text=False,
                                               resolve_entities=False,
                                               dtd_validation=False)

            # load the file and set a reference to the dm group
            try:
                self.__tree = etree.parse(self._buffer, self.__xmlparser)
            except etree.XMLSyntaxError as err:
                self.invalidfile = True
                self.fileerror = err.msg

                if self.stoponerror:
                    raise DMXmlParseError(err, ReturnCodes.E_XML_PARSE_ERROR)

            if not self.invalidfile:
                self.__root = self.__tree.getroot()

                try:
                    check_root_element(self.__root, etree)
                except ValueError as err:
                    self.invalidfile = True
                    self.fileerror = err

                    if self.stoponerror:
                        raise DMXmlParseError(err, ReturnCodes.E_XML_PARSE_ERROR)

                if not self.invalidfile:
                    # check for DocBook 5 namespace in start tag
                    try:
                        self.check_docbook5_ns()

                        # check for docmanager element
                        self.__docmanager = self.__tree.find("//dm:docmanager", namespaces=NS)

                        if self.__docmanager is None:
                            log.info("No docmanager element found")
                            self.create_group()
                        else:
                            log.debug("Found docmanager element %s", self.__docmanager.getparent())
                    except DMNotDocBook5File as err:
                        if self.stoponerror == True:
                            raise DMNotDocBook5File(err.errorstr, err.error)