Example #1
0
def makealias(qrc_files, recursive, verbose):
    """Command to generate aliases for each resources contained in qrc files.

    Args:
        qrc_files (tuple): Paths to qrc files that need to generate alias.
        recursive (bool): If True, search recursively qrc filed from launching
            directory.
        verbose (bool): Boolean determining if messages will be displayed.

    """
    # Check all qrc files recursively
    if recursive:
        recursive_qrc_files = recursive_file_search("qrc")

        # Check if recursive option find qrc files
        if not recursive_qrc_files:
            v.error("Could not find any qrc files.")
            raise click.Abort()
        else:
            write_alias(recursive_qrc_files, verbose)

    # Process given files or warns user if none
    if qrc_files:
        write_alias(qrc_files, verbose)
    elif not recursive:
        v.warning("No qrc files was given to process.")
Example #2
0
def makerc(qrc_files, recursive, verbose):
    """Generate python module for corresponding given qrc files.

    Args:
        qrc_files (tuple): Paths to qrc files that need to generate its
            corresponding rc files.
        recursive (bool): If True, search recursively qrc filed from launching
            directory.
        verbose (bool): Boolean determining if messages will be displayed.

    """
    # Check all qrc files recursively
    if recursive:
        recursive_qrc_files = recursive_file_search("qrc")

        # Check if recursive option find qrc files
        if not recursive_qrc_files:
            v.error("Could not find any qrc files")
        else:
            generate_rc(recursive_qrc_files, verbose)

    # Process given files or warns user if none
    if qrc_files:
        generate_rc(qrc_files, verbose)
    elif not recursive:
        v.warning("No qrc files was given to process.")
Example #3
0
def write_alias(qrc_files, verbose):
    """Write alias for resources within qrc files.

    Alias are base in basename of theses resources. In the case where two
    resource files would have the same name, and so, the same alias, the
    script warns the user of incriminated files.

    Args:
        qrc_files (list or tuple): A list containing path to qrc files.
        verbose (bool): True if the user pass '-v' or '--verbose' option
            to see what's happening.
    """
    warnings = []  # List containing all warnings message
    # Loop over all provided qrc files
    for qrc_file in qrc_files:
        tree = etree.parse(qrc_file)
        root = tree.getroot()

        # Inform which qrc file is processed
        v.info("Current file: {}".format(qrc_file), verbose)

        # Iterate over each qresource containing file resources
        for qresource in root.iter(tag="qresource"):
            # Alias are prefixed by qresource prefix so we check only
            # duplication within qresource
            aliases = []
            # Iterate over each file that doesn't have already an alias
            for resource in qresource.iter(tag="file"):
                alias = os.path.basename(resource.text)
                if alias not in aliases:
                    if not resource.attrib.get("alias", None):
                        resource.set("alias", alias)

                        # Inform which alias is given to the current resource
                        v.info("resource: '{}' => {}".format(
                            resource.text, alias), verbose)
                else:
                    # Add same alias warning
                    warnings.append(WARNING_TEMPLATE.format(
                        alias, qrc_file, qresource.attrib.get(
                            "prefix", ""))
                    )
                    break

                # Append created alias to used aliases in current qresource
                aliases.append(alias)

        # Rewrite qrc file
        tree.write(qrc_file)

    # Warning user of which resources that could not receive alias
    # because of duplication
    for message in warnings:
        v.warning(message)
Example #4
0
    def rm_dirs(self, qrc, directories, commit=True):
        """Remove a directory from dirs key in the given qrc section.

        Args:
            qrc (str): Qrc file name like "res.qrc"
            directories (str or list): Relative paths between directories and
                project dir.
                ex: "\nres\ntest/res\n/res" or ["res"] for one dir in a list
            commit (Optional[bool]): if true save changes in the config file.

        Raises:
            :class:`PyqtcliConfigError`: Raised when `qrc` isn't recorded in the
                project config file.

        """
        try:
            dirs = self.cparser[qrc].get("dirs", None)

            if not isinstance(directories, list):
                if directories.startswith("\n"):
                    directories = directories.splitlines()[1:]
                else:
                    directories = [directories]

            if dirs is None:  # There is no resources folders recorded yet
                v.warning(
                    ("There is no recorded resources folders "
                     "to delete in {}").format(qrc))
            else:
                # Delete each relative path contains in directory argument
                dirs = self.get_dirs(qrc)
                for rel_path in directories:
                    try:
                        dirs.remove(rel_path)
                    except ValueError:
                        v.warning(
                            ("Directory \'{}\' isn't recorded "
                             "for \'{}\' and so cannot be deleted".format(
                                   rel_path, qrc)))

                # Save updated dirs variable
                dirs = "\n".join(dirs)
                if dirs == "":  # Avoid extra '\n' dirs is empty
                    self.cparser.set(qrc, "dirs", dirs)
                else:
                    self.cparser.set(qrc, "dirs", "\n" + dirs)

                if commit:
                    self.save()

        except KeyError:
            raise PyqtcliConfigError(
                "Error: No \'{}\' section in .pyqtclirc.".format(qrc))
Example #5
0
def addqres(config, qrc_path, res_folders, alias, verbose):
    """
    Add <qresource> element with a prefix attribute set to the base name of
    the given folder of resources. All resources contained in this folder are
    recorded in qresource as <file> subelement.

    Args:
        config (:class:`PyqtcliConfig`): PyqtcliConfig object representing
            project config file.
        qrc_path (str): Path to the qrc file that need to add the qresource
            nodes corresponding to `res_folders`.
        res_folders (tuple): Paths to folders of resources to record.
        alias (bool): If True, aliases will be generated while resources are
            recorded.
        verbose (bool): Boolean determining if messages will be displayed.
    """
    qrc_file = read_qrc(qrc_path)
    recorded_dirs = config.get_dirs(qrc_file.name)

    # Remove duplication in res_folders with a set
    res_folders = set(res_folders)

    # Process each resource folders passed
    for folder in res_folders:
        # rel_path => relative path of folder from project directory
        rel_path = os.path.relpath(folder, config.dir_path)

        # Check if given resources folder has already been recorded
        if rel_path in recorded_dirs:
            v.warning("You have already added \'{}\' to {}.".format(
                    folder, qrc_file.name))
            continue

        # Add folder to dirs variable in the config file
        try:
            config.add_dirs(qrc_file.name, rel_path, commit=False)
        except PyqtcliConfigError:
            v.error("{} isn't part of the project.".format(qrc_path))
            raise click.Abort()

        # Add qresource to qrc file
        prefix = get_prefix(folder)
        qrc_file.add_qresource(prefix)
        fill_qresource(qrc_file, folder, prefix)

        v.info("qresource with prefix: \'{}\' has been recorded in {}.".format(
                prefix, qrc_path), verbose)

    qrc_file.build()
    config.save()

    if alias:
        write_alias([qrc_file.path], verbose)
Example #6
0
def test_rmqres_with_non_recorded_res_folder(config, test_resources):
    runner = CliRunner()

    runner.invoke(pyqtcli, ["new", "qrc"])

    result = runner.invoke(pyqtcli, ["rmqres", "res.qrc", "resources"])
    assert format_msg(result.output) == v.warning(
        "There is no recorded resources folders to delete in res.qrc\n"
    )
Example #7
0
def test_addqres_duplication(config, test_resources):
    runner = CliRunner()

    # Generate a qrc file named res and update config file
    runner.invoke(pyqtcli, ["new", "qrc"])

    # Add qresources corresponding to resources folder
    runner.invoke(pyqtcli, ["addqres", "res.qrc", "resources"])

    # Add the same qresource
    result = runner.invoke(pyqtcli, ["addqres", "res.qrc", "resources"])

    assert format_msg(result.output) == v.warning("You have already added 'resources' to res.qrc.\n")
Example #8
0
def update(config, qrc_files, project, verbose):
    """Update project's qrc files through information stored in config file.

    Args:
        config (:class:`PyqtcliConfig`): PyqtcliConfig object representing
            project config file.
        qrc_files (tuple): Paths to qrc files that need to get updated.
        project (bool): If True, all registered qrc files will be updated.
        verbose (bool): Boolean determining if messages will be displayed.

    """
    if project:
        recursive_qrc_files = recursive_file_search("qrc")
        update_project(recursive_qrc_files, config, verbose)
        generate_rc(recursive_qrc_files, verbose)

    elif qrc_files:
        update_project(qrc_files, config, verbose)
        generate_rc(qrc_files, verbose)

    else:
        v.warning("No qrc files to update")
Example #9
0
def test_delete_recorded_and_not_recorded_res_folders(config, test_resources):
    shutil.copytree("resources", "test")

    runner = CliRunner()

    # Generate a qrc file named res and update config file
    runner.invoke(pyqtcli, ["new", "qrc"])

    # Test addqres with default option
    runner.invoke(pyqtcli, ["addqres", "res.qrc", "resources"])

    # Remove resources folder config file and qrc
    result = runner.invoke(pyqtcli, ["rmqres", "res.qrc", "test"])
    assert format_msg(result.output) == v.warning(
        (
            "Directory 'test' isn't recorded for 'res.qrc' and so "
            "cannot be deleted\n"
        )
    )
Example #10
0
def generate_rc(qrc_files, verbose):
    """Generate python module to access qrc resources via pyrcc5 tool.

    Args:
        qrc_files (list or tuple): A tuple containing all paths to qrc files
            to process.
        verbose (bool): True if the user pass '-v' or '--verbose' option
            to see what's happening.

    Examples:
        This example will create two files: res_rc.py and qtc/another_res_rc.py

        >>> generate_rc(["res.qrc", "qrc/another_res.qrc"])

    """
    for qrc_file in qrc_files:
        # rc file name
        result_file = os.path.splitext(qrc_file)[0] + "_rc.py"

        # generate rc file corresponding to qrc file
        result = subprocess.run(["pyrcc5", qrc_file, "-o", result_file],
                                stderr=subprocess.PIPE)

        # Case where qrc has no more resources -> can't generate rc file
        if result.stderr == NO_QRESOURCE:
            v.warning(
                ("{} has no more resources and cannot generates its "
                 "corresponding rc file.").format(qrc_file))
            continue
        elif result.stderr.startswith(INVALID_QRC):
            v.warning("Qrc file: \'{}\' is not valid.".format(qrc_file))
            continue
        elif result.stderr:
            v.warning(result.stderr.decode("utf-8"))
            continue

        v.info("Python qrc file '{}' created.".format(result_file), verbose)
Example #11
0
def update_project(qrc_files, config, verbose):
    """Update given qrc files through information stored in the config file.

    Args:
        qrc_files (list or tuple): list of paths to qrc files.
        config (:class:`pyqtcli.config.PyqtcliConfig`): Project config file.
        verbose (bool): If True display information about the process

    """
    for qrc_file in qrc_files:
        qrc = read_qrc(qrc_file)          # qrc file to update
        dirs = config.get_dirs(qrc.name)  # resources folders recorded in qrc

        for res_dir in dirs:
            if os.path.abspath(res_dir) == os.path.dirname(
                    find_project_config()):
                v.warning("Can't update automatically a qrc file where "
                          "resources are in the same directory as the project "
                          "one.")
                continue

            # prefix identify qresource in qrc file
            prefix = get_prefix_update(res_dir)

            # Verify the recorded directory still exist and otherwise remove
            # it from dirs variable in config file. It's corresponding in qrc
            # file is deleted with its <file> children
            if not os.path.isdir(res_dir):
                config.rm_dirs(qrc.name, res_dir)
                qrc.remove_qresource(prefix)
                qrc.build()

                v.info(
                    ("The resource folder {} has been manually removed.\n"
                     "It's resources are removed from {} and deleted "
                     "from .pyqtclirc").format(res_dir, qrc_file), verbose
                )
                continue

            # Loop over the folder of resources to check file addition or
            # deletion to report in qrc file
            resources = qrc.list_resources(prefix)
            if prefix == "/":
                # list of resources at the root
                res = []
                for path in os.listdir(res_dir):
                    if os.path.isfile(os.path.join(res_dir, path)):
                        res.append(path)

                new_qresource_dirs = [r for r in res if r not in dirs]
                for resource in res:
                    # A new folder in the root of resources folder as been added
                    resource = os.path.join(res_dir, resource)
                    if os.path.isdir(os.path.join(res_dir, resource)) and \
                            resource in new_qresource_dirs:
                        qrc.add_qresource(
                            get_prefix_update(os.path.join(res_dir, resource)),
                            res_dir
                        )
                        v.info("{} added to {} as {}".format(
                                res_dir, qrc_file, prefix), verbose)
                    else:
                        # Add the resource if not recorded
                        if resource not in resources:
                            qrc.add_file(resource, prefix)
                            v.info("{} added to {}".format(resource, qrc_file),
                                   verbose)
                        # Remove the resource if it's recorded
                        elif resource in resources:
                            resources.remove(resource)
            else:
                for root, dirs, files in os.walk(res_dir):
                    for resource in files:
                        resource = os.path.join(root, resource)
                        # Add the resource if not recorded
                        if resource not in resources:
                            qrc.add_file(resource, prefix)
                            v.info("{} added to {}".format(resource, qrc_file),
                                   verbose)
                        # Remove the resource if it's recorded
                        elif resource in resources:
                            resources.remove(resource)

            # Remaining resources in resources variable have been deleted
            # manually and so removed from qrc
            for res in resources:
                qrc.remove_resource(res, prefix)
                v.info(
                    ("The resource \'{}\' has been manually deleted and so"
                     " removed from {}").format(res, qrc_file), verbose)

        # Save modifications to qrc file
        qrc.build()