From 768ef0b6bcc609d4b124e61549688175fea464b1 Mon Sep 17 00:00:00 2001 From: Timmy Welch Date: Sun, 18 Feb 2024 01:40:49 -0800 Subject: [PATCH] Fix rar exe handling --- comicapi/archivers/rar.py | 30 +++++++++++++++++++++++++++-- comicapi/utils.py | 8 ++++++++ comictaggerlib/ctsettings/plugin.py | 20 ++++++++++++------- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/comicapi/archivers/rar.py b/comicapi/archivers/rar.py index b0f7d53..dc09105 100644 --- a/comicapi/archivers/rar.py +++ b/comicapi/archivers/rar.py @@ -260,7 +260,21 @@ class RarArchiver(Archiver): return True def is_writable(self) -> bool: - return bool(self.exe and (os.path.exists(self.exe) or shutil.which(self.exe))) + try: + if bool(self.exe and (os.path.exists(self.exe) or shutil.which(self.exe))): + return ( + subprocess.run( + (self.exe,), + startupinfo=self.startupinfo, + capture_output=True, + cwd=self.path.absolute().parent, + ) + .stdout.strip() + .startswith(b"RAR") + ) + except OSError: + ... + return False def extension(self) -> str: return ".cbr" @@ -271,7 +285,19 @@ class RarArchiver(Archiver): @classmethod def is_valid(cls, path: pathlib.Path) -> bool: if rar_support: - return rarfile.is_rarfile(str(path)) + # Try using exe + orig = rarfile.UNRAR_TOOL + rarfile.UNRAR_TOOL = cls.exe + try: + return rarfile.is_rarfile(str(path)) and rarfile.tool_setup(sevenzip=False, sevenzip2=False, force=True) + except rarfile.RarCannotExec as e: + rarfile.UNRAR_TOOL = orig + + # Fallback to standard + try: + return rarfile.is_rarfile(str(path)) and rarfile.tool_setup(sevenzip=False, sevenzip2=False, force=True) + except rarfile.RarCannotExec as e: + logger.info(e) return False def get_rar_obj(self) -> rarfile.RarFile | None: diff --git a/comicapi/utils.py b/comicapi/utils.py index cb44cfe..795e7f9 100644 --- a/comicapi/utils.py +++ b/comicapi/utils.py @@ -236,6 +236,14 @@ def add_to_path(dirname: str) -> None: os.environ["PATH"] = os.pathsep.join(paths) +def remove_from_path(dirname: str) -> None: + if dirname: + dirname = os.path.abspath(dirname) + paths = [os.path.normpath(x) for x in split(os.environ["PATH"], os.pathsep) if dirname != os.path.normpath(x)] + + os.environ["PATH"] = os.pathsep.join(paths) + + def xlate_int(data: Any) -> int | None: data = xlate_float(data) if data is None: diff --git a/comictaggerlib/ctsettings/plugin.py b/comictaggerlib/ctsettings/plugin.py index f4f604e..96a9851 100644 --- a/comictaggerlib/ctsettings/plugin.py +++ b/comictaggerlib/ctsettings/plugin.py @@ -62,16 +62,22 @@ def register_talker_settings(manager: settngs.Manager, talkers: dict[str, ComicT def validate_archive_settings(config: settngs.Config[ct_ns]) -> settngs.Config[ct_ns]: - if "archiver" not in config[1]: - return config cfg = settngs.normalize_config(config, file=True, cmdline=True, default=False) for archiver in comicapi.comicarchive.archivers: + group = group_for_plugin(archiver()) exe_name = settngs.sanitize_name(archiver.exe) - if exe_name in cfg[0][group_for_plugin(archiver())] and cfg[0][group_for_plugin(archiver())][exe_name]: - if os.path.basename(cfg[0][group_for_plugin(archiver())][exe_name]) == archiver.exe: - comicapi.utils.add_to_path(os.path.dirname(cfg[0][group_for_plugin(archiver())][exe_name])) - else: - archiver.exe = cfg[0][group_for_plugin(archiver())][exe_name] + if not exe_name: + continue + + if exe_name in cfg[0][group] and cfg[0][group][exe_name]: + path = cfg[0][group][exe_name] + name = os.path.basename(path) + # If the path is not the basename then this is a relative or absolute path. + # Ensure it is absolute + if path != name: + path = os.path.abspath(path) + + archiver.exe = path return config