diff options
| author | copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> | 2026-02-04 13:50:44 +0000 |
|---|---|---|
| committer | copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> | 2026-02-04 13:50:44 +0000 |
| commit | ee0dfbeec44706c8b498f6582d1cfa8e5f765453 (patch) | |
| tree | 23a44574f7282ebfd7175bc65e2015f30a62e4c2 | |
| parent | e63129be2aca1418d29d06e746dd00dffb8bd126 (diff) | |
| download | decky-installer-ee0dfbeec44706c8b498f6582d1cfa8e5f765453.tar.gz decky-installer-ee0dfbeec44706c8b498f6582d1cfa8e5f765453.zip | |
Add custom store configuration support to mock server and installer
Co-authored-by: tranch <5999732+tranch@users.noreply.github.com>
| -rw-r--r-- | decky_plugin_installer.py | 88 | ||||
| -rw-r--r-- | mock_decky_server.py | 76 |
2 files changed, 161 insertions, 3 deletions
diff --git a/decky_plugin_installer.py b/decky_plugin_installer.py index 7c70235..5814427 100644 --- a/decky_plugin_installer.py +++ b/decky_plugin_installer.py @@ -229,9 +229,91 @@ async def run_installer(target_id: int, store_url: str) -> None: raise RuntimeError("Installation did not complete successfully") +async def configure_store_url(store_url: str) -> None: + """Configure custom store URL in Decky settings.""" + client = DeckyClient() + try: + log(f"Connecting to Decky server at {client.host}:{client.port}...") + token = await client.get_token() + await client.connect(token) + + log(f"Setting custom store URL: {store_url}") + await client.send(CALL, "utilities/settings/set", ["store_url", store_url]) + + # Wait for reply + msg = await client.recv() + if msg is None: + raise RuntimeError("Connection closed by server") + + m_type = msg.get("type") + + if m_type == REPLY: + log(f"Store URL configured successfully: {msg.get('result')}") + elif m_type == ERROR: + log(f"Server error: {msg.get('error')}") + raise RuntimeError(f"Failed to set store URL: {msg.get('error')}") + + except Exception as e: + log(f"Error: {e}") + raise + finally: + await client.close() + + +async def get_store_url() -> str: + """Get the configured custom store URL from Decky settings.""" + client = DeckyClient() + try: + log(f"Connecting to Decky server at {client.host}:{client.port}...") + token = await client.get_token() + await client.connect(token) + + log("Getting configured store URL...") + await client.send(CALL, "utilities/settings/get", ["store_url", "https://plugins.deckbrew.xyz/plugins"]) + + # Wait for reply + msg = await client.recv() + if msg is None: + raise RuntimeError("Connection closed by server") + + m_type = msg.get("type") + + if m_type == REPLY: + store_url = msg.get('result') + log(f"Current store URL: {store_url}") + return store_url + elif m_type == ERROR: + log(f"Server error: {msg.get('error')}") + raise RuntimeError(f"Failed to get store URL: {msg.get('error')}") + + raise RuntimeError("Unexpected response type") + + except Exception as e: + log(f"Error: {e}") + raise + finally: + await client.close() + + if __name__ == "__main__": parser = argparse.ArgumentParser(description="Decky Plugin Installer") - parser.add_argument("--store-url", default="http://127.0.0.1:1337/plugins") - parser.add_argument("--target-id", type=int, default=42) + parser.add_argument("--store-url", default="http://127.0.0.1:1337/plugins", + help="Plugin store URL to fetch plugins from") + parser.add_argument("--target-id", type=int, default=42, + help="Plugin ID to install") + parser.add_argument("--configure-store", metavar="URL", + help="Configure custom store URL in Decky settings") + parser.add_argument("--get-store", action="store_true", + help="Get the configured custom store URL") args = parser.parse_args() - asyncio.run(run_installer(**vars(args))) + + if args.configure_store: + # Configure store URL + asyncio.run(configure_store_url(args.configure_store)) + elif args.get_store: + # Get configured store URL + asyncio.run(get_store_url()) + else: + # Run installer + asyncio.run(run_installer(**{k: v for k, v in vars(args).items() + if k in ['target_id', 'store_url']})) diff --git a/mock_decky_server.py b/mock_decky_server.py index 7a7341e..7a74dcd 100644 --- a/mock_decky_server.py +++ b/mock_decky_server.py @@ -42,6 +42,9 @@ CSRF_TOKEN = "decky-" + os.urandom(16).hex() # Plugin install requests storage (simulates PluginBrowser.install_requests) install_requests: Dict[str, Dict[str, str]] = {} +# Settings storage (simulates SettingsManager) +settings_store: Dict[str, Any] = {} + logging.basicConfig( level=logging.INFO, @@ -198,6 +201,8 @@ def handle_call_route( "utilities/install_plugin": handle_install_plugin, "utilities/confirm_plugin_install": handle_confirm_plugin_install, "utilities/cancel_plugin_install": handle_cancel_plugin_install, + "utilities/settings/get": handle_get_setting, + "utilities/settings/set": handle_set_setting, } if route not in routes: @@ -409,6 +414,77 @@ def handle_cancel_plugin_install( return None +def handle_get_setting( + sock: socket.socket, + args: List[Any], + config: Dict[str, bool] +) -> Any: + """Handle utilities/settings/get route. + + Corresponds to: + - utilities.py async def get_setting() (line 272) + - settings.py def getSetting() (line 58) + + Function signature from utilities.py: + async def get_setting(self, key: str, default: Any) + + Args: + sock: The WebSocket socket (unused). + args: [key, default]. + config: Server configuration (unused). + + Returns: + The setting value or the default if not found. + """ + if len(args) < 1: + raise ValueError("get_setting requires key argument") + + key = args[0] + default = args[1] if len(args) > 1 else None + + value = settings_store.get(key, default) + logger.info("[get_setting] key=%s, default=%s, value=%s", key, default, value) + + return value + + +def handle_set_setting( + sock: socket.socket, + args: List[Any], + config: Dict[str, bool] +) -> Any: + """Handle utilities/settings/set route. + + Corresponds to: + - utilities.py async def set_setting() (line 275) + - settings.py def setSetting() (line 61) + + Function signature from utilities.py: + async def set_setting(self, key: str, value: Any) + + Args: + sock: The WebSocket socket (unused). + args: [key, value]. + config: Server configuration (unused). + + Returns: + The value that was set. + + Raises: + ValueError: If key or value is missing. + """ + if len(args) < 2: + raise ValueError("set_setting requires key and value arguments") + + key = args[0] + value = args[1] + + settings_store[key] = value + logger.info("[set_setting] key=%s, value=%s", key, value) + + return value + + def _do_install(sock: socket.socket, artifact: str, name: str, version: str, hash_val: str) -> None: """Simulate the installation process with progress events. |
