diff --git a/gui/v2/actions/disable_profiles.py b/gui/v2/actions/disable_profiles.py new file mode 100644 index 0000000..cfa912e --- /dev/null +++ b/gui/v2/actions/disable_profiles.py @@ -0,0 +1,65 @@ +from core.models.session.SessionProfile import SessionProfile +from core.models.system.SystemProfile import SystemProfile +from core.controllers.ProfileController import ProfileController +from core.models.BaseProfile import BaseProfile + +# not currently used, but can be added: +# application_version_observer, +# client_observer, +# invoice_observer, + +from gui.v2.infrastructure.setup_observers import ( + connection_observer, + profile_observer, + ticket_observer, +) + +import inspect + +def filter_profiles_by_type(profile_data: list) -> tuple: + """ + Purpose: + Isolate system and session profiles into separate lists + Why: + Session profiles must be disabled first before System profiles. + Called by: + worker_thread's disable_all_profiles + """ + system_profiles = [] + session_profiles = [] + for profile_id in profile_data: + profile = ProfileController.get(int(profile_id)) + + if isinstance(profile, SessionProfile): + session_profiles.append(profile) + + elif isinstance(profile, SystemProfile): + system_profiles.append(profile) + + else: + print(f"Skipping/discarding unknown profile {profile_id} type {type(profile)} full info: {profile}") + + return session_profiles, system_profiles + + +def disable_profile_via_controller(profile: BaseProfile): + """ + Purpose: + Disable a profile via the controller + Why: + Inspect signature deals with changing observers + Called by: + worker_thread's disable_all_profiles + """ + kwargs = { + 'profile_observer': profile_observer, + 'ticket_observer': ticket_observer, + 'connection_observer': connection_observer, + } + supported = inspect.signature(ProfileController.disable).parameters + ProfileController.disable( + profile, + **{key: value for key, value in kwargs.items() if key in supported} + ) + + # We return nothing, because core signals via observers for success. And raises errors for failure. \ No newline at end of file diff --git a/gui/v2/workers/worker_thread.py b/gui/v2/workers/worker_thread.py index 6092659..4d968c6 100755 --- a/gui/v2/workers/worker_thread.py +++ b/gui/v2/workers/worker_thread.py @@ -1,6 +1,7 @@ import shlex import subprocess -import inspect +# import inspect +import time from PyQt6.QtCore import QThread, pyqtSignal @@ -23,6 +24,11 @@ from core.errors.exceptions import SudoScript, MissingPreReqs, FirewallError from core.models.Result import Result, ResultError from core.services.helpers.install_dependencies import setup_singbox_binary as install_singbox_binary +from gui.v2.actions.disable_profiles import ( + filter_profiles_by_type, + disable_profile_via_controller +) + from gui.v2.infrastructure.setup_observers import ( application_version_observer, client_observer, @@ -53,17 +59,17 @@ class WorkerThread(QThread): self.is_running = True self.is_disabling = False - def _disable_profile(self, profile): - kwargs = { - 'profile_observer': profile_observer, - 'ticket_observer': ticket_observer, - 'connection_observer': connection_observer, - } - supported = inspect.signature(ProfileController.disable).parameters - ProfileController.disable( - profile, - **{key: value for key, value in kwargs.items() if key in supported} - ) + # def _disable_profile(self, profile): + # kwargs = { + # 'profile_observer': profile_observer, + # 'ticket_observer': ticket_observer, + # 'connection_observer': connection_observer, + # } + # supported = inspect.signature(ProfileController.disable).parameters + # ProfileController.disable( + # profile, + # **{key: value for key, value in kwargs.items() if key in supported} + # ) def run(self): if self.action == 'LIST_PROFILES': @@ -176,11 +182,28 @@ class WorkerThread(QThread): self.finished.emit(False) def disable_all_profiles(self): + """ + Purpose: + Loop through all profiles in the class data, + Classify them, and disable them. + Why: + Session profiles must be disabled first before System profiles. + Called by: + Same Class run() + """ + session_profiles, system_profiles = filter_profiles_by_type(self.profile_data) try: - for profile_id in self.profile_data: - profile = ProfileController.get(int(profile_id)) - if isinstance(profile, SessionProfile) or isinstance(profile, SystemProfile): - self._disable_profile(profile) + # SESSION + for profile in session_profiles: + disable_profile_via_controller(profile) + print("finished with session profiles. now moving onto session profiles") + + if session_profiles and system_profiles: + time.sleep(1) + + # SYSTEM + for profile in system_profiles: + disable_profile_via_controller(profile) self.text_output.emit("All profiles were successfully disabled") except SudoScript as e: self.text_output.emit(str(e)) @@ -188,7 +211,8 @@ class WorkerThread(QThread): self.text_output.emit(str(e)) except MissingPreReqs as e: self.text_output.emit(str(e)) - except Exception: + except Exception as e: + print(f"Error: {str(e)}") self.text_output.emit("An error occurred when disabling profile") finally: self.finished.emit(True) @@ -289,7 +313,7 @@ class WorkerThread(QThread): try: profile = ProfileController.get(int(self.profile_data['id'])) if profile: - self._disable_profile(profile) + disable_profile_via_controller(profile) else: self.text_output.emit( f"No profile found with ID: {self.profile_data['id']}")