diff --git a/README.rst b/README.rst index 7e281e6..6053463 100644 --- a/README.rst +++ b/README.rst @@ -157,8 +157,8 @@ Options used: * ``wrapper`` (required) with ``cd32`` as an value * ``wrapper_archive`` (required) path to the archive with CD32 iso/cue/wav -* ``wrapper_archiver`` (conditionally required) archiver to use for storage - save state +* ``wrapper_archiver`` (optional) archiver to use for storage save state - + default ``7z``. * ``wrapper_gui_msg`` (optional) if set to "1", will display a graphical message during extracting files * ``wrapper_save_state`` (optional) if set to "1", will load/archive save state @@ -175,7 +175,7 @@ fragment of configuration file is saved as ``ChaosEngine.fs-uae``: [config] wrapper = cd32 wrapper_archive = ChaosEngine.7z - wrapper_archiver = 7z + wrapper_archiver = zip wrapper_gui_msg = 1 amiga_model = CD32 @@ -219,10 +219,12 @@ archive Options used: * ``wrapper`` (required) with ``archive`` as an value -* ``wrapper_archive`` (required) path to the archive with assets (usually means - whole system directories, floppies or hard disk images) -* ``wrapper_archiver`` (conditionally required) archiver to use for storage - save state +* ``wrapper_archive`` (optional) path to the archive with assets (usually means + whole system directories, floppies or hard disk images), defaults to same + name as configuration file with some detected archive extension. Note, that + name is case sensitive +* ``wrapper_archiver`` (optional) archiver to use for storage save state - + default ``7z``. * ``wrapper_gui_msg`` (optional) if set to "1", will display a graphical message during extracting files * ``wrapper_persist_data`` (optional) if set to "1", will compress (possibly @@ -277,7 +279,8 @@ savestate Options used: * ``wrapper`` (required) with ``archive`` as an value -* ``wrapper_archiver`` (required) archiver to use for storage save state +* ``wrapper_archiver`` (optional) archiver to use for storage save state - + default ``7z``. This module is primarily used to run emulator with read only media attached (like images of floppies or uncompressed CD-ROMs) and its purpose is to diff --git a/fs_uae_wrapper/base.py b/fs_uae_wrapper/base.py index a4323ed..8fac4b7 100644 --- a/fs_uae_wrapper/base.py +++ b/fs_uae_wrapper/base.py @@ -237,9 +237,9 @@ class Base(object): return True if 'wrapper_archiver' not in self.all_options: - logging.error("Configuration lacks of required " - "`wrapper_archiver' option.") - return False + logging.warning("Configuration lacks of optional " + "`wrapper_archiver' option, fall back to 7z") + self.all_options['wrapper_archiver'] = "7z" if not path.which(self.all_options['wrapper_archiver']): logging.error("Cannot find archiver `%s'.", @@ -295,8 +295,30 @@ class ArchiveBase(Base): validation_result = super(ArchiveBase, self)._validate_options() if 'wrapper_archive' not in self.all_options: - sys.stderr.write("Configuration lacks of required " - "`wrapper_archive' option.\n") - validation_result = False + logging.warning("Configuration lacks of optional `wrapper_archive'" + " option.\n") + wrapper_archive = self._get_wrapper_archive_name() + if wrapper_archive is None: + logging.error("Configuration lacks of optional " + "`wrapper_archive', cannot deduct the name by " + "configuration file name.\n") + validation_result = False + self.all_options['wrapper_archive'] = wrapper_archive return validation_result + + def _get_wrapper_archive_name(self): + """ + Return full path to the archive name using configuration file + basename and appending one of the expected archive extensions. + """ + basename = os.path.splitext(self.conf_file)[0] + file_list = os.listdir('.') + for fname in file_list: + for ext in ('.7z', '.lha', '.lzx', '.zip', '.rar', '.tar', '.tgz', + '.tar.gz', '.tar.bz2', '.tar.xz'): + if ((basename + ext).lower() == fname.lower() and + basename == os.path.splitext(fname)[0]): + return fname + return None + diff --git a/fs_uae_wrapper/utils.py b/fs_uae_wrapper/utils.py index 7c5e70a..3e67eed 100644 --- a/fs_uae_wrapper/utils.py +++ b/fs_uae_wrapper/utils.py @@ -4,6 +4,7 @@ Misc utilities import configparser import logging import os +import pathlib import shutil import subprocess @@ -19,8 +20,8 @@ class CmdOption(dict): def add(self, option): """parse and add option to the dictionary""" if not option.startswith('--'): - raise AttributeError("Cannot add option `%s' to the dictionary" % - option) + raise AttributeError(f"Cannot add option {option} to the " + f"dictionary") if '=' in option: key, val = option.split('=', 1) key = key[2:].strip() @@ -35,9 +36,9 @@ class CmdOption(dict): ret_list = [] for key, val in self.items(): if val != '1': - ret_list.append('--%(k)s=%(v)s' % {'k': key, 'v': val}) + ret_list.append(f'--{key}={val}') else: - ret_list.append('--%(k)s' % {'k': key}) + ret_list.append(f'--{key}') return ret_list @@ -87,7 +88,7 @@ def create_archive(arch_name, title='', params=None): """ msg = '' if title: - msg = "Creating archive for `%s'. Please be patient" % title + msg = f"Creating archive for `{title}'. Please be patient" return operate_archive(arch_name, 'create', msg, params) @@ -97,7 +98,7 @@ def extract_archive(arch_name, title='', params=None): """ msg = '' if title: - msg = "Extracting files for `%s'. Please be patient" % title + msg = f"Extracting files for `{title}'. Please be patient" return operate_archive(arch_name, 'extract', msg, params) @@ -143,8 +144,9 @@ def interpolate_variables(string, config_path, base=None): _string = string if '$CONFIG' in string: - conf_path = os.path.dirname(os.path.abspath(config_path)) - string = os.path.abspath(string.replace('$CONFIG', conf_path)) + conf_path = pathlib.Path(config_path).resolve().parent + string = str(pathlib.Path(string.replace('$CONFIG', str(conf_path))) + .resolve()) if '$HOME' in string: string = string.replace('$HOME', os.path.expandvars('$HOME')) diff --git a/pyproject.toml b/pyproject.toml index f6b05ae..b22a972 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ description = "Automate archives support and state saves for fs-uae" readme = "README.rst" requires-python = ">=3.8" keywords = ["uae", "fs-uae", "amiga", "emulator", "wrapper"] -version = "0.9.0" +version = "0.9.1" classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", diff --git a/tests/test_base.py b/tests/test_base.py index cba407c..133b96b 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -286,7 +286,7 @@ class TestBase(TestCase): which.return_value = '7z' bobj.all_options = {'wrapper': 'dummy', 'wrapper_save_state': '1'} - self.assertFalse(bobj._validate_options()) + self.assertTrue(bobj._validate_options()) bobj.all_options = {'wrapper': 'dummy', 'wrapper_save_state': '1', diff --git a/tests/test_savestate.py b/tests/test_savestate.py index 688eda5..8843a60 100644 --- a/tests/test_savestate.py +++ b/tests/test_savestate.py @@ -73,7 +73,7 @@ class TestSaveState(TestCase): self.assertFalse(arch._validate_options()) arch.all_options['wrapper'] = 'savestate' - self.assertFalse(arch._validate_options()) + self.assertTrue(arch._validate_options()) arch.all_options['wrapper_archiver'] = 'rar' self.assertTrue(arch._validate_options())