From e9f0cab1eea900ecd83d82e47ed5e6995354483d Mon Sep 17 00:00:00 2001 From: Teichoui Date: Sat, 25 Apr 2026 22:49:06 -0500 Subject: [PATCH] Add EQBCS post-update autorun option --- src/redfetch/main.py | 17 +++++++++++++++ src/redfetch/settings.toml | 1 + src/redfetch/terminal_ui.py | 33 ++++++++++++++++++++++++++++ src/redfetch/terminal_ui.tcss | 4 ++-- tests/test_auto_run_eqbcs.py | 41 +++++++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 tests/test_auto_run_eqbcs.py diff --git a/src/redfetch/main.py b/src/redfetch/main.py index ddf35af..4f7be25 100644 --- a/src/redfetch/main.py +++ b/src/redfetch/main.py @@ -183,6 +183,22 @@ def prompt_auto_run_macroquest() -> None: console.print("MacroQuest path not found. Please check your configuration.") +def auto_run_eqbcs_if_enabled() -> None: + """Start EQBCS after a successful update when configured to do so.""" + if os.environ.get("CI") == "true" or sys.platform != "win32": + return + + auto_run_eqbcs = config.settings.from_env(config.settings.ENV).get("AUTO_RUN_EQBCS", False) + if not auto_run_eqbcs: + return + + mq_path = utils.get_vvmq_path() + if mq_path: + processes.run_executable(mq_path, "EQBCS.exe") + else: + console.print("MacroQuest path not found. Please check your configuration.") + + async def handle_download_watched_async(db_path: str, headers: dict) -> bool: """Run the main 'update watched' flow using async network calls.""" if await net.is_mq_down(): @@ -207,6 +223,7 @@ async def handle_download_watched_async(db_path: str, headers: dict) -> bool: db_path, headers, navmesh_override=navmesh_override ) if success: + auto_run_eqbcs_if_enabled() prompt_auto_run_macroquest() return True return False diff --git a/src/redfetch/settings.toml b/src/redfetch/settings.toml index 84ecf24..6ccf9a2 100644 --- a/src/redfetch/settings.toml +++ b/src/redfetch/settings.toml @@ -8,6 +8,7 @@ [DEFAULT] DOWNLOAD_FOLDER = "@format {env[REDFETCH_DATA_DIR]}/Downloads" EQPATH = "" +AUTO_RUN_EQBCS = false # ======================================== # XenForo OAuth2 diff --git a/src/redfetch/terminal_ui.py b/src/redfetch/terminal_ui.py index f8ace13..943beaf 100644 --- a/src/redfetch/terminal_ui.py +++ b/src/redfetch/terminal_ui.py @@ -501,6 +501,14 @@ def compose(self) -> ComposeResult: ), tooltip="Automatically run Very Vanilla MQ after successful updates.", ) + yield Label("Start EQBCS post-update:", classes="left_middle") + yield Switch( + id="auto_run_eqbcs", + value=config.settings.from_env(current_env).get( + "AUTO_RUN_EQBCS", False + ), + tooltip="Automatically run EQBCS.exe after successful updates.", + ) if sys.platform == "win32": yield Label("Desktop shortcut:", classes="left_middle") yield Switch( @@ -561,6 +569,9 @@ def sync_from_app(self, app: "Redfetch") -> None: auto_run_vvmq_switch = self.query_one("#auto_run_vvmq", Switch) auto_run_vvmq_switch.value = settings_for_env.get("AUTO_RUN_VVMQ", None) + auto_run_eqbcs_switch = self.query_one("#auto_run_eqbcs", Switch) + auto_run_eqbcs_switch.value = settings_for_env.get("AUTO_RUN_EQBCS", False) + auto_terminate_switch = self.query_one("#auto_terminate_processes", Switch) auto_terminate_switch.value = settings_for_env.get("AUTO_TERMINATE_PROCESSES", None) @@ -674,6 +685,8 @@ def on_switch_changed(self, event: Switch.Changed) -> None: self.app.handle_toggle_navmesh(event.value) elif event.switch.id == "auto_run_vvmq": self.app.handle_toggle_auto_run_vvmq(event.value) + elif event.switch.id == "auto_run_eqbcs": + self.app.handle_toggle_auto_run_eqbcs(event.value) elif event.switch.id == "auto_terminate_processes": self.app.handle_toggle_auto_terminate_processes(event.value) elif event.switch.id == "desktop_shortcut": @@ -1517,6 +1530,16 @@ def handle_toggle_auto_run_vvmq(self, value: bool) -> None: if main_screen: main_screen.query_one("#auto_run_vvmq", Switch).value = value + def handle_toggle_auto_run_eqbcs(self, value: bool) -> None: + main_screen = self._get_main_screen() + current_value = config.settings.from_env(self.current_env).get('AUTO_RUN_EQBCS', False) + if current_value != value: + config.update_setting(['AUTO_RUN_EQBCS'], value, env=self.current_env) + state = "enabled" if value else "disabled" + self.notify(f"Auto-run EQBCS is now {state}") + if main_screen: + main_screen.query_one("#auto_run_eqbcs", Switch).value = value + # # Settings updaters # @@ -1688,6 +1711,15 @@ def run_executable(self, folder_path: str, executable_name: str, args=None) -> N else: self.notify(f"Failed to start {executable_name}", severity="error") + def auto_run_eqbcs_if_enabled(self) -> None: + """Start EQBCS after a successful update when configured to do so.""" + if sys.platform != "win32": + return + + auto_run_eqbcs = config.settings.from_env(self.current_env).get("AUTO_RUN_EQBCS", False) + if auto_run_eqbcs: + self.run_executable(utils.get_vvmq_path(), "EQBCS.exe") + def run_myseq_executable(self) -> None: myseq_path = utils.get_myseq_path() if myseq_path: @@ -1929,6 +1961,7 @@ def update_complete(self, result: bool, button: Button) -> None: self.set_timer(6, lambda: main_screen.reset_button("update_resource_id", "default")) elif button.id == "update_watched": if sys.platform == 'win32': + self.auto_run_eqbcs_if_enabled() auto_run = config.settings.from_env(self.current_env).get('AUTO_RUN_VVMQ', None) if auto_run is True: self.run_executable(utils.get_vvmq_path(), "MacroQuest.exe") diff --git a/src/redfetch/terminal_ui.tcss b/src/redfetch/terminal_ui.tcss index 5b5359a..f85cd32 100644 --- a/src/redfetch/terminal_ui.tcss +++ b/src/redfetch/terminal_ui.tcss @@ -237,7 +237,7 @@ Label { #dropdowns_grid { min-width: 30; } -#dl_path_input, #eq_path_input, #vvmq_path_input, #auto_terminate_processes, #auto_run_vvmq, #desktop_shortcut { +#dl_path_input, #eq_path_input, #vvmq_path_input, #auto_terminate_processes, #auto_run_vvmq, #auto_run_eqbcs, #desktop_shortcut { column-span: 3; } #myseq, #ionbc, #navmesh { @@ -564,4 +564,4 @@ UninstallScreen Button { #no_uninstall:hover { background: $surface-darken-1; border-top: tall $surface; -} \ No newline at end of file +} diff --git a/tests/test_auto_run_eqbcs.py b/tests/test_auto_run_eqbcs.py new file mode 100644 index 0000000..0ee909c --- /dev/null +++ b/tests/test_auto_run_eqbcs.py @@ -0,0 +1,41 @@ +import importlib +from types import SimpleNamespace +from unittest.mock import MagicMock, patch + +from redfetch import config + + +class _SettingsStub: + ENV = "LIVE" + + def __init__(self, values): + self._values = values + + def from_env(self, env): + return self._values + + +def test_main_auto_run_eqbcs_if_enabled(monkeypatch): + monkeypatch.setattr(config, "settings", _SettingsStub({"AUTO_RUN_EQBCS": True}), raising=False) + main = importlib.import_module("redfetch.main") + + with patch("redfetch.main.utils.get_vvmq_path", return_value="C:/MQ"), \ + patch("redfetch.main.processes.run_executable") as run_mock, \ + patch("redfetch.main.sys.platform", "win32"), \ + patch.dict("redfetch.main.os.environ", {}, clear=True): + main.auto_run_eqbcs_if_enabled() + + run_mock.assert_called_once_with("C:/MQ", "EQBCS.exe") + + +def test_terminal_ui_auto_run_eqbcs_if_enabled(monkeypatch): + monkeypatch.setattr(config, "settings", _SettingsStub({"AUTO_RUN_EQBCS": True}), raising=False) + Redfetch = importlib.import_module("redfetch.terminal_ui").Redfetch + + app = SimpleNamespace(current_env="LIVE", run_executable=MagicMock()) + + with patch("redfetch.terminal_ui.utils.get_vvmq_path", return_value="C:/MQ"), \ + patch("redfetch.terminal_ui.sys.platform", "win32"): + Redfetch.auto_run_eqbcs_if_enabled(app) + + app.run_executable.assert_called_once_with("C:/MQ", "EQBCS.exe")