From 5e490f00a14f698a11d38962d44692235f0f3864 Mon Sep 17 00:00:00 2001 From: FriendsOfGalaxy Date: Thu, 29 Jul 2021 15:00:42 +0200 Subject: [PATCH] version 0.40 --- src/plugin.py | 6 ++-- src/uri_scheme_handler.py | 36 +++++++++++------------ src/version.py | 8 ++++- tests/test_uri_scheme_handler.py | 50 ++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 21 deletions(-) create mode 100644 tests/test_uri_scheme_handler.py diff --git a/src/plugin.py b/src/plugin.py index c360218..0204736 100755 --- a/src/plugin.py +++ b/src/plugin.py @@ -309,8 +309,10 @@ async def prepare_local_size_context(self, game_ids: List[GameId]) -> Dict[str, async def get_local_size(self, game_id: GameId, context: Dict[str, pathlib.PurePath]) -> Optional[int]: try: return parse_map_crc_for_total_size(context[game_id]) - except (KeyError, FileNotFoundError) as e: - raise UnknownError(f"Manifest for game {game_id} is not found: {repr(e)} | context: {context}") + except FileNotFoundError: + return None + except KeyError: + raise UnknownError("Manifest not found") @staticmethod def _get_multiplayer_id(offer) -> Optional[MultiplayerId]: diff --git a/src/uri_scheme_handler.py b/src/uri_scheme_handler.py index 2ab5c39..83045f2 100755 --- a/src/uri_scheme_handler.py +++ b/src/uri_scheme_handler.py @@ -1,42 +1,42 @@ import platform + if platform.system().lower() == "windows": import winreg - import shlex import os - def is_uri_handler_installed(protocol): - try: - key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, r"{}\shell\open\command".format(protocol)) - except OSError: - return False + def _get_path_from_cmd_template(cmd_template) -> str: + return cmd_template.replace("\"", "").partition("%")[0].strip() + def is_uri_handler_installed(protocol) -> bool: try: - executable_template = winreg.QueryValue(key, None) - splitted_exec = shlex.split(executable_template) - if not splitted_exec: - return False - return os.path.exists(splitted_exec[0]) - except ValueError: + with winreg.OpenKey( + winreg.HKEY_CLASSES_ROOT, r"{}\shell\open\command".format(protocol) + ) as key: + executable_template = winreg.QueryValue(key, None) + path = _get_path_from_cmd_template(executable_template) + return os.path.exists(path) + except OSError: return False - finally: - winreg.CloseKey(key) - return True elif platform.system().lower() == "darwin": from CoreServices.LaunchServices import LSCopyDefaultHandlerForURLScheme from AppKit import NSWorkspace - def is_uri_handler_installed(protocol): + def is_uri_handler_installed(protocol) -> bool: bundle_id = LSCopyDefaultHandlerForURLScheme(protocol) if not bundle_id: return False - return NSWorkspace.sharedWorkspace().absolutePathForAppBundleWithIdentifier_(bundle_id) is not None + return ( + NSWorkspace.sharedWorkspace().absolutePathForAppBundleWithIdentifier_(bundle_id) + is not None + ) + else: - def is_uri_handler_installed(protocol): + def is_uri_handler_installed(protocol) -> bool: return False diff --git a/src/version.py b/src/version.py index 90e6886..993061e 100755 --- a/src/version.py +++ b/src/version.py @@ -1,6 +1,12 @@ -__version__ = "0.39" +__version__ = "0.40" __changelog__ = { + "unreleased":"""""", + "0.40": + """ + - `get_local_size`: return `None` if map.crc not found instead of raising error + - fix detecting installed launcher & games when EA Desktop is installed + """, "0.39": """ - update Galaxy API version to 0.68 diff --git a/tests/test_uri_scheme_handler.py b/tests/test_uri_scheme_handler.py new file mode 100644 index 0000000..eefc8e6 --- /dev/null +++ b/tests/test_uri_scheme_handler.py @@ -0,0 +1,50 @@ +import platform + +import pytest + +from uri_scheme_handler import is_uri_handler_installed + + +@pytest.mark.skipif(platform.system().lower() != "windows", reason="windows registry") +@pytest.mark.parametrize( + "reg_value_template", + [ + pytest.param('{} "%1"', id="Origin case"), + pytest.param('"{}" "%1"', id="EA Desktop case"), + pytest.param('{} "%1" "%2"', id="more params (hypotetical)"), + pytest.param("{} %1", id="no quotes around param (hypotetical)"), + pytest.param("{}", id="just exe without params (hypotetical)"), + ], +) +def test_win_reg_uri_handler_installed(mocker, reg_value_template): + launcher_path = r"C:\Program Files\EA Desktop Example Path\EALauncher.exe" + reg_value = reg_value_template.format(launcher_path) + + mocker.patch("winreg.OpenKey") + mocker.patch("winreg.QueryValue", return_value=reg_value) + mocker.patch("os.path.exists", side_effect=lambda x: x == launcher_path) + + assert is_uri_handler_installed(mocker.Mock()) == True + + +@pytest.mark.skipif(platform.system().lower() != "windows", reason="windows registry") +@pytest.mark.parametrize( + "problem_patch_config", + [ + {"target": "winreg.OpenKey", "side_effect": OSError}, + {"target": "winreg.OpenKey", "side_effect": FileNotFoundError}, + {"target": "winreg.QueryValue", "side_effect": PermissionError}, + {"target": "os.path.exists", "return_value": False}, + ], +) +def test_win_reg_uri_hanlder_not_installed(mocker, problem_patch_config): + # "installed" case patches + mocker.patch("winreg.OpenKey") + mocker.patch("winreg.QueryValue", return_value="path"), + mocker.patch("os.path.exists", return_value=True) + assert is_uri_handler_installed(mocker.Mock()) == True, "test preconfiguration failed" + + # problem patch + mocker.patch(**problem_patch_config) + + assert is_uri_handler_installed(mocker.Mock()) == False