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)
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)
def test_simple_rmqres(config, test_resources): runner = CliRunner() # Generate a qrc file named res and update config file runner.invoke(pyqtcli, ["new", "qrc"]) # Add resources folder config file and qrc runner.invoke(pyqtcli, ["addqres", "res.qrc", "resources"]) # Remove resources folder config file and qrc result = runner.invoke(pyqtcli, ["rmqres", "res.qrc", "resources", "-v"]) # Parse qrc file qrcfile = read_qrc("res.qrc") # Check qresource has been deleted with pytest.raises(QresourceError) as e: qrcfile.get_qresource("/resources") assert format_msg(str(e.value)) == ( "Error: No <qresource> node corresponding to '/resources' prefix" ) # Check res_folder has been removed from dirs variable of config file config.read() assert config.get_dirs("res.qrc") == [] assert format_msg(result.output) == v.info( "Resources folder: \'resources\' has been removed in res.qrc.\n" )
def qrc(config, path, res_folder, verbose): """Create a new qrc file. Args: config (:class:`PyqtcliConfig`): PyqtcliConfig object representing project config file. path (str): Path where create the new qrc file. res_folder (str): Path to the folder of resources . verbose (bool): Boolean determining if messages will be displayed. """ file_path, name = os.path.split(path) qrc_file = QRCFile(name, file_path) # Verify qrc file doesn't already exists if name in config.get_qrcs(): v.error("A qrc file named \'{}\' already exists".format(name)) raise click.Abort() # Add a new section for the created qrc file config.cparser.add_section(name) config.cparser.set(name, "path", qrc_file.path) if res_folder: generate_qrc(qrc_file, res_folder, build=False) # Get the relative path to the folder of resources from project # directory to add its sub dirs to the dirs variable in the # corresponding qrc section of config file rel_path = os.path.relpath(res_folder, config.dir_path) resources = os.listdir(rel_path) # If there is resources that are not in folder add the res_folder in the # dirs key of the config file. config.add_dirs(name, rel_path, commit=False) for d in resources: if os.path.isdir(os.path.join(rel_path, d)): config.add_dirs(name, os.path.join(rel_path, d), commit=False) qrc_file.build() config.save() v.info("Qrc file \'{}\' has been created.".format(path), verbose)
def __init__(self, path=None, msg="", verbose=True): self.cparser = configparser.ConfigParser() self.dir_path = os.getcwd() if path: self.path = os.path.abspath(path) else: found_config = find_project_config() self.path = found_config or os.path.join(os.getcwd(), self.INI_FILE) # Create a new ini file if not exist if not os.path.isfile(self.path): self.initialize() if msg is None or msg == "": msg = "The project named: \'{}\' was initialized in {}".format( os.path.basename(os.getcwd()), os.getcwd()) v.info(msg, verbose) self.read()
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)
def rmqres(config, qrc_path, res_folders, verbose): """ Remove a <qresource> element with a prefix attribute set to the base name of the given folder of resources. All <file> subelements are removed too. Args: config (:class:`PyqtcliConfig`): PyqtcliConfig object representing project config file. qrc_path (str): Path to the qrc file that need to remove the qresource nodes corresponding to `res_folders`. res_folders (tuple): Paths to folders of resources to remove. verbose (bool): Boolean determining if messages will be displayed. """ qrcfile = read_qrc(qrc_path) # Remove duplication in res_folders with a set res_folders = set(res_folders) folders = [os.path.relpath(f, config.dir_path) for f in res_folders] # remove folder to dirs variable in the config file try: config.rm_dirs(qrcfile.name, folders, commit=False) except PyqtcliConfigError: v.error("{} isn't part of the project.".format(qrc_path)) raise click.Abort() for folder in folders: # Remove qresource to qrc file prefix = get_prefix(folder) qrcfile.remove_qresource(prefix) v.info("Resources folder: \'{}\' has been removed in {}.".format( folder, qrc_path), verbose) config.save() qrcfile.build()
def test_new_default(config): runner = CliRunner() result = runner.invoke(pyqtcli, ["new", "qrc", "-v"]) # Check qrc file is generated assert result.exit_code == 0 assert os.path.isfile("res.qrc") # Check content of newly generated qrc file tree = etree.parse("res.qrc") assert etree.tostring(tree) == b"<RCC/>" # Check qrc file has been added to project the config file config.read() assert ["res.qrc"] == config.get_qrcs() # Test verbose assert format_msg(result.output) == v.info( "Qrc file \'res.qrc\' has been created.\n")
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()