forked from Support/sp-hydra-veil-gui
update: added new qt preloader flow
This commit is contained in:
parent
86348ce2e3
commit
28a9787658
7 changed files with 264 additions and 51 deletions
|
|
@ -26,8 +26,15 @@ core_logger.propagate = False
|
|||
from gui.v2.infrastructure.navigator import Navigator
|
||||
from gui.v2.infrastructure.setup_observers import setup_observers
|
||||
from gui.v2.infrastructure.connection_manager import ConnectionManager
|
||||
from gui.v2.infrastructure.page_registry import PRELOAD_ORDER, PRELOAD_SKIP
|
||||
from gui.v2.infrastructure.page_registry import (
|
||||
PRELOAD_ORDER,
|
||||
PRELOAD_SKIP,
|
||||
ASYNC_PREPARE,
|
||||
REGULAR_FLOW_ONLY,
|
||||
PAGE_REGISTRY,
|
||||
)
|
||||
from gui.v2.workers.worker_thread import WorkerThread
|
||||
from gui.v2.workers.page_data_worker import PageDataWorker
|
||||
from gui.v2.ui.builders.bottom_section import create_bottom_section
|
||||
from gui.v2.ui.builders.top_section import create_top_section
|
||||
from gui.v2.ui.builders.system_tray import init_system_tray
|
||||
|
|
@ -48,6 +55,7 @@ from gui.v2.actions.flags import (
|
|||
has_shown_fast_mode_prompt,
|
||||
mark_fast_mode_prompt_shown,
|
||||
set_fast_mode_enabled,
|
||||
is_fast_registration_enabled,
|
||||
check_first_launch,
|
||||
)
|
||||
from gui.v2.actions.profile_data import (
|
||||
|
|
@ -170,6 +178,10 @@ class CustomWindow(QMainWindow):
|
|||
self._preload_done = 0
|
||||
self._preload_failed = 0
|
||||
self._preload_skipped_runtime = 0
|
||||
self._preload_dispatched = 0
|
||||
self._preload_inflight = 0
|
||||
self._preload_workers = {}
|
||||
self._preload_summary_emitted = False
|
||||
self._preload_t_start = 0.0
|
||||
self._preload_timer = QTimer(self)
|
||||
self._preload_timer.setSingleShot(True)
|
||||
|
|
@ -202,15 +214,26 @@ class CustomWindow(QMainWindow):
|
|||
def _start_background_preload(self):
|
||||
import time
|
||||
self._preload_queue = [n for n in PRELOAD_ORDER if n not in PRELOAD_SKIP]
|
||||
fast_mode = is_fast_registration_enabled(self.gui_config_file)
|
||||
skipped_regular = []
|
||||
if fast_mode:
|
||||
skipped_regular = [n for n in self._preload_queue if n in REGULAR_FLOW_ONLY]
|
||||
self._preload_queue = [n for n in self._preload_queue if n not in REGULAR_FLOW_ONLY]
|
||||
self._preload_total = len(self._preload_queue)
|
||||
self._preload_done = 0
|
||||
self._preload_failed = 0
|
||||
self._preload_skipped_runtime = 0
|
||||
self._preload_dispatched = 0
|
||||
self._preload_inflight = 0
|
||||
self._preload_summary_emitted = False
|
||||
self._preload_t_start = time.perf_counter()
|
||||
print(f"[preload] ============================================================", flush=True)
|
||||
print(f"[preload] starting background preload: {self._preload_total} pages queued", flush=True)
|
||||
print(f"[preload] order : {', '.join(self._preload_queue)}", flush=True)
|
||||
print(f"[preload] skipped : {', '.join(sorted(PRELOAD_SKIP))} (unsafe init)", flush=True)
|
||||
if fast_mode:
|
||||
print(f"[preload] fastmode: ON -> skipping regular-flow pages: "
|
||||
f"{', '.join(skipped_regular) if skipped_regular else '(none)'}", flush=True)
|
||||
print(f"[preload] gap : 250 ms between loads, 700 ms initial delay", flush=True)
|
||||
print(f"[preload] ============================================================", flush=True)
|
||||
self._preload_timer.start(700)
|
||||
|
|
@ -221,19 +244,73 @@ class CustomWindow(QMainWindow):
|
|||
self._preload_skipped_runtime += 1
|
||||
print(f"[preload] {skipped:30s} SKIP (user navigated here first)", flush=True)
|
||||
if not self._preload_queue:
|
||||
self._emit_preload_summary()
|
||||
self._maybe_emit_preload_summary()
|
||||
return
|
||||
idx = self._preload_done + self._preload_failed + 1
|
||||
self._preload_dispatched += 1
|
||||
idx = self._preload_dispatched
|
||||
name = self._preload_queue.pop(0)
|
||||
print(f"[preload] ---- {idx}/{self._preload_total} ----", flush=True)
|
||||
ok = self.navigator.preload(name)
|
||||
if ok:
|
||||
self._preload_done += 1
|
||||
if name in ASYNC_PREPARE:
|
||||
self._dispatch_async_preload(name)
|
||||
else:
|
||||
self._preload_failed += 1
|
||||
ok = self.navigator.preload(name)
|
||||
if ok:
|
||||
self._preload_done += 1
|
||||
else:
|
||||
self._preload_failed += 1
|
||||
if self._preload_queue:
|
||||
self._preload_timer.start(250)
|
||||
else:
|
||||
self._maybe_emit_preload_summary()
|
||||
|
||||
def _dispatch_async_preload(self, name):
|
||||
module_path, class_name = PAGE_REGISTRY[name]
|
||||
print(f"[preload] {name:30s} ASYNC {module_path}.{class_name}", flush=True)
|
||||
worker = PageDataWorker(name, module_path, class_name, self)
|
||||
worker.data_ready.connect(self._on_preload_data_ready)
|
||||
worker.failed.connect(self._on_preload_failed)
|
||||
worker.finished.connect(lambda n=name: self._cleanup_preload_worker(n))
|
||||
self._preload_workers[name] = worker
|
||||
self._preload_inflight += 1
|
||||
worker.start()
|
||||
|
||||
def _on_preload_data_ready(self, name, payload):
|
||||
self._preload_inflight -= 1
|
||||
if name in self.navigator._instances:
|
||||
print(f"[preload] {name:30s} SKIP (already cached, async result dropped)", flush=True)
|
||||
else:
|
||||
try:
|
||||
page = self.navigator._instantiate(name, prepared=payload)
|
||||
self.navigator.register_instance(name, page)
|
||||
self._preload_done += 1
|
||||
print(f"[preload] {name:30s} OK (async, cached={len(self.navigator._instances)}, "
|
||||
f"stack_size={self.page_stack.count()})", flush=True)
|
||||
except Exception as e:
|
||||
self._preload_failed += 1
|
||||
print(f"[preload] {name:30s} FAIL (async build) {type(e).__name__}: {e}", flush=True)
|
||||
self._maybe_emit_preload_summary()
|
||||
|
||||
def _on_preload_failed(self, name, error):
|
||||
self._preload_inflight -= 1
|
||||
print(f"[preload] {name:30s} FAIL (async prepare) {error}", flush=True)
|
||||
if name not in self.navigator._instances:
|
||||
ok = self.navigator.preload(name)
|
||||
if ok:
|
||||
self._preload_done += 1
|
||||
else:
|
||||
self._preload_failed += 1
|
||||
self._maybe_emit_preload_summary()
|
||||
|
||||
def _cleanup_preload_worker(self, name):
|
||||
worker = self._preload_workers.pop(name, None)
|
||||
if worker is not None:
|
||||
worker.deleteLater()
|
||||
|
||||
def _maybe_emit_preload_summary(self):
|
||||
if self._preload_summary_emitted:
|
||||
return
|
||||
if not self._preload_queue and self._preload_inflight == 0:
|
||||
self._preload_summary_emitted = True
|
||||
self._emit_preload_summary()
|
||||
|
||||
def _emit_preload_summary(self):
|
||||
|
|
|
|||
|
|
@ -35,6 +35,13 @@ def mark_fast_mode_prompt_shown(gui_config_file):
|
|||
save_gui_config(gui_config_file, config)
|
||||
|
||||
|
||||
def is_fast_registration_enabled(gui_config_file):
|
||||
config = load_gui_config(gui_config_file)
|
||||
if not config:
|
||||
return False
|
||||
return config.get("registrations", {}).get("fast_registration_enabled", False)
|
||||
|
||||
|
||||
def set_fast_mode_enabled(gui_config_file, enabled):
|
||||
config = load_gui_config(gui_config_file)
|
||||
if config is None:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import importlib
|
|||
import time
|
||||
import traceback
|
||||
|
||||
from gui.v2.infrastructure.page_registry import PAGE_REGISTRY
|
||||
from gui.v2.infrastructure.page_registry import PAGE_REGISTRY, ASYNC_PREPARE
|
||||
|
||||
|
||||
class Navigator:
|
||||
|
|
@ -11,18 +11,29 @@ class Navigator:
|
|||
self.custom_window = custom_window
|
||||
self._instances = {}
|
||||
|
||||
def get_class(self, name):
|
||||
module_path, class_name = PAGE_REGISTRY[name]
|
||||
module = importlib.import_module(module_path)
|
||||
return getattr(module, class_name)
|
||||
|
||||
def _instantiate(self, name, prepared=None):
|
||||
cls = self.get_class(name)
|
||||
if name in ASYNC_PREPARE:
|
||||
return cls(self.page_stack, self.custom_window, prepared=prepared)
|
||||
return cls(self.page_stack, self.custom_window)
|
||||
|
||||
def register_instance(self, name, page):
|
||||
self.page_stack.addWidget(page)
|
||||
self._instances[name] = page
|
||||
|
||||
def navigate(self, name):
|
||||
page = self._instances.get(name)
|
||||
if page is None:
|
||||
if name not in PAGE_REGISTRY:
|
||||
self._warn_not_migrated(name)
|
||||
return
|
||||
module_path, class_name = PAGE_REGISTRY[name]
|
||||
module = importlib.import_module(module_path)
|
||||
cls = getattr(module, class_name)
|
||||
page = cls(self.page_stack, self.custom_window)
|
||||
self.page_stack.addWidget(page)
|
||||
self._instances[name] = page
|
||||
page = self._instantiate(name)
|
||||
self.register_instance(name, page)
|
||||
self.page_stack.setCurrentIndex(self.page_stack.indexOf(page))
|
||||
|
||||
def preload(self, name):
|
||||
|
|
@ -36,11 +47,8 @@ class Navigator:
|
|||
print(f"[preload] {name:30s} LOAD {module_path}.{class_name}", flush=True)
|
||||
t0 = time.perf_counter()
|
||||
try:
|
||||
module = importlib.import_module(module_path)
|
||||
cls = getattr(module, class_name)
|
||||
page = cls(self.page_stack, self.custom_window)
|
||||
self.page_stack.addWidget(page)
|
||||
self._instances[name] = page
|
||||
page = self._instantiate(name)
|
||||
self.register_instance(name, page)
|
||||
dt_ms = (time.perf_counter() - t0) * 1000.0
|
||||
print(f"[preload] {name:30s} OK ({dt_ms:6.1f} ms, "
|
||||
f"cached={len(self._instances)}, stack_size={self.page_stack.count()})",
|
||||
|
|
|
|||
|
|
@ -38,6 +38,23 @@ PRELOAD_SKIP = {
|
|||
"ticket_prep",
|
||||
}
|
||||
|
||||
ASYNC_PREPARE = {
|
||||
"settings",
|
||||
}
|
||||
|
||||
REGULAR_FLOW_ONLY = {
|
||||
"protocol",
|
||||
"location",
|
||||
"hidetor",
|
||||
"residential",
|
||||
"tor",
|
||||
"connection",
|
||||
"screen",
|
||||
"browser",
|
||||
"wireguard",
|
||||
"sync_screen",
|
||||
}
|
||||
|
||||
PRELOAD_ORDER = [
|
||||
"settings",
|
||||
"editor",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ class Page(QWidget):
|
|||
self.selected_residential = []
|
||||
self.buttons = []
|
||||
|
||||
@staticmethod
|
||||
def prepare_data(custom_window):
|
||||
return None
|
||||
|
||||
def add_selected_profile(self, profile):
|
||||
self.selected_profiles.clear()
|
||||
self.selected_wireguard.clear()
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ from core.errors.logger import logger as core_logger
|
|||
|
||||
from gui.v2.actions.key_interpretation import interpret_key_results
|
||||
from gui.v2.actions.profile_order import normalize_profile_order
|
||||
from gui.v2.infrastructure.page_registry import PAGE_REGISTRY
|
||||
from gui.v2.infrastructure.setup_observers import ticket_observer
|
||||
from gui.v2.ui.pages.Page import Page
|
||||
from gui.v2.ui.popups.confirmation_popup import ConfirmationPopup
|
||||
|
|
@ -46,17 +47,21 @@ from gui.v2.ui.styles.styles import (
|
|||
)
|
||||
from gui.v2.ui.widgets.clickable_label import ClickableValueLabel
|
||||
from gui.v2.ui.widgets.terminal_widget import TerminalWidget
|
||||
from gui.v2.workers.page_data_worker import PageDataWorker
|
||||
from gui.v2.workers.ticketing_worker_thread import TicketingWorkerThread
|
||||
from gui.v2.workers.worker_thread import WorkerThread
|
||||
|
||||
|
||||
class Settings(Page):
|
||||
def __init__(self, page_stack, main_window, parent=None):
|
||||
def __init__(self, page_stack, main_window, parent=None, prepared=None):
|
||||
super().__init__("Settings", page_stack, main_window, parent)
|
||||
self.font_style = f"font-family: '{self.custom_window.open_sans_family}';"
|
||||
|
||||
self.update_status = main_window
|
||||
self.update_logging = main_window
|
||||
self._prepared = prepared if prepared is not None else self.prepare_data(main_window)
|
||||
self._settings_refresh_seq = 0
|
||||
self._settings_workers = set()
|
||||
self.button_reverse.setVisible(True)
|
||||
self.button_reverse.setEnabled(True)
|
||||
self.button_reverse.clicked.connect(self.reverse)
|
||||
|
|
@ -64,6 +69,52 @@ class Settings(Page):
|
|||
self.title.setText("Settings")
|
||||
self.setup_ui()
|
||||
|
||||
@staticmethod
|
||||
def prepare_data(custom_window):
|
||||
profiles = ProfileController.get_all()
|
||||
profile_order = normalize_profile_order(
|
||||
getattr(custom_window, 'gui_config_file', None), profiles.keys())
|
||||
current_connection = custom_window.get_current_connection()
|
||||
try:
|
||||
endpoint_verification_enabled = ConfigurationController.get_endpoint_verification_enabled()
|
||||
except Exception:
|
||||
endpoint_verification_enabled = False
|
||||
return {
|
||||
"profiles": profiles,
|
||||
"profile_order": profile_order,
|
||||
"current_connection": current_connection,
|
||||
"endpoint_verification_enabled": endpoint_verification_enabled,
|
||||
"systemwide_enabled": Settings._read_systemwide_enabled(),
|
||||
"bwrap_enabled": Settings._read_bwrap_enabled(),
|
||||
"gui_config": custom_window._load_gui_config(),
|
||||
"ticket_failure": custom_window.get_ticket_verification_failure(),
|
||||
}
|
||||
|
||||
def _prepared_value(self, key, loader):
|
||||
if self._prepared is not None and key in self._prepared:
|
||||
return self._prepared[key]
|
||||
return loader()
|
||||
|
||||
@staticmethod
|
||||
def _read_systemwide_enabled():
|
||||
try:
|
||||
privilege_policy = PolicyController.get('privilege')
|
||||
if privilege_policy is not None:
|
||||
return PolicyController.is_instated(privilege_policy)
|
||||
except Exception:
|
||||
pass
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _read_bwrap_enabled():
|
||||
try:
|
||||
capability_policy = PolicyController.get('capability')
|
||||
if capability_policy is not None:
|
||||
return PolicyController.is_instated(capability_policy)
|
||||
except Exception:
|
||||
pass
|
||||
return False
|
||||
|
||||
def setup_ui(self):
|
||||
main_container = QWidget(self)
|
||||
main_container.setGeometry(0, 0, 800, 520)
|
||||
|
|
@ -198,11 +249,13 @@ class Settings(Page):
|
|||
return page
|
||||
|
||||
def create_delete_profile_buttons(self):
|
||||
profiles = ProfileController.get_all()
|
||||
profiles = self._prepared_value("profiles", ProfileController.get_all)
|
||||
|
||||
profile_ids = normalize_profile_order(
|
||||
getattr(self.update_status, 'gui_config_file', None),
|
||||
profiles.keys())
|
||||
profile_ids = self._prepared_value(
|
||||
"profile_order",
|
||||
lambda: normalize_profile_order(
|
||||
getattr(self.update_status, 'gui_config_file', None),
|
||||
profiles.keys()))
|
||||
|
||||
for index, profile_id in enumerate(profile_ids):
|
||||
profile = profiles[profile_id]
|
||||
|
|
@ -600,7 +653,7 @@ class Settings(Page):
|
|||
|
||||
def update_debug_profile_list(self):
|
||||
self.debug_profile_selector.clear()
|
||||
profiles = ProfileController.get_all()
|
||||
profiles = self._prepared_value("profiles", ProfileController.get_all)
|
||||
system_profiles = {pid: profile for pid, profile in profiles.items(
|
||||
) if isinstance(profile, SystemProfile)}
|
||||
|
||||
|
|
@ -904,7 +957,7 @@ class Settings(Page):
|
|||
|
||||
self.profile_selector = QComboBox()
|
||||
self.profile_selector.setStyleSheet(self.get_combobox_style())
|
||||
profiles = ProfileController.get_all()
|
||||
profiles = self._prepared_value("profiles", ProfileController.get_all)
|
||||
if profiles:
|
||||
for profile_id, profile in profiles.items():
|
||||
self.profile_selector.addItem(
|
||||
|
|
@ -1039,7 +1092,7 @@ class Settings(Page):
|
|||
self.verification_profile_selector = QComboBox()
|
||||
self.verification_profile_selector.setStyleSheet(
|
||||
self.get_combobox_style())
|
||||
profiles = ProfileController.get_all()
|
||||
profiles = self._prepared_value("profiles", ProfileController.get_all)
|
||||
if profiles:
|
||||
for profile_id, profile in profiles.items():
|
||||
self.verification_profile_selector.addItem(
|
||||
|
|
@ -1134,7 +1187,9 @@ class Settings(Page):
|
|||
self.endpoint_verification_checkbox = QCheckBox(page)
|
||||
self.endpoint_verification_checkbox.setGeometry(180, 415, 30, 30)
|
||||
self.endpoint_verification_checkbox.setChecked(
|
||||
ConfigurationController.get_endpoint_verification_enabled())
|
||||
self._prepared_value(
|
||||
"endpoint_verification_enabled",
|
||||
ConfigurationController.get_endpoint_verification_enabled))
|
||||
self.endpoint_verification_checkbox.setStyleSheet(
|
||||
self.get_checkbox_style())
|
||||
self.endpoint_verification_checkbox.show()
|
||||
|
|
@ -1295,6 +1350,31 @@ class Settings(Page):
|
|||
|
||||
def showEvent(self, event):
|
||||
super().showEvent(event)
|
||||
self._settings_refresh_seq += 1
|
||||
seq = self._settings_refresh_seq
|
||||
module_path, class_name = PAGE_REGISTRY["settings"]
|
||||
worker = PageDataWorker(
|
||||
"settings", module_path, class_name, self.custom_window)
|
||||
worker.data_ready.connect(
|
||||
lambda name, payload, s=seq: self._on_settings_data_ready(payload, s))
|
||||
worker.failed.connect(
|
||||
lambda name, error: self._on_settings_data_failed(error))
|
||||
worker.finished.connect(
|
||||
lambda w=worker: self._cleanup_settings_worker(w))
|
||||
self._settings_workers.add(worker)
|
||||
worker.start()
|
||||
|
||||
def _on_settings_data_failed(self, error):
|
||||
core_logger.warning(f"Settings data refresh failed: {error}")
|
||||
|
||||
def _cleanup_settings_worker(self, worker):
|
||||
self._settings_workers.discard(worker)
|
||||
worker.deleteLater()
|
||||
|
||||
def _on_settings_data_ready(self, payload, seq):
|
||||
if seq != self._settings_refresh_seq:
|
||||
return
|
||||
self._prepared = payload
|
||||
|
||||
current_index = self.content_layout.currentIndex()
|
||||
|
||||
|
|
@ -1407,7 +1487,7 @@ class Settings(Page):
|
|||
layout = QGridLayout(widget)
|
||||
layout.setSpacing(10)
|
||||
|
||||
profiles = ProfileController.get_all()
|
||||
profiles = self._prepared_value("profiles", ProfileController.get_all)
|
||||
total_profiles = len(profiles)
|
||||
session_profiles = sum(1 for p in profiles.values()
|
||||
if isinstance(p, SessionProfile))
|
||||
|
|
@ -1439,7 +1519,8 @@ class Settings(Page):
|
|||
|
||||
config_path = Constants.HV_CONFIG_HOME
|
||||
|
||||
current_connection = self.update_status.get_current_connection()
|
||||
current_connection = self._prepared_value(
|
||||
"current_connection", self.update_status.get_current_connection)
|
||||
|
||||
if current_connection is not None:
|
||||
current_connection = current_connection.capitalize()
|
||||
|
|
@ -1697,7 +1778,8 @@ class Settings(Page):
|
|||
inventory_layout.addWidget(self.refresh_tickets_button)
|
||||
layout.addWidget(inventory_group)
|
||||
|
||||
saved_failure = self.update_status.get_ticket_verification_failure()
|
||||
saved_failure = self._prepared_value(
|
||||
"ticket_failure", self.update_status.get_ticket_verification_failure)
|
||||
has_failure = saved_failure is not None
|
||||
|
||||
recovery_group = QGroupBox("Verification Failure Recovery")
|
||||
|
|
@ -1954,7 +2036,8 @@ class Settings(Page):
|
|||
|
||||
def load_logs_settings(self) -> None:
|
||||
try:
|
||||
config = self.update_status._load_gui_config()
|
||||
config = self._prepared_value(
|
||||
"gui_config", self.update_status._load_gui_config)
|
||||
if config and "logging" in config:
|
||||
self.enable_gui_logging.setChecked(
|
||||
config["logging"]["gui_logging_enabled"])
|
||||
|
|
@ -2103,7 +2186,8 @@ class Settings(Page):
|
|||
layout.addLayout(button_layout)
|
||||
|
||||
layout.addStretch()
|
||||
self.load_systemwide_settings()
|
||||
self.load_systemwide_settings(
|
||||
self._prepared_value("systemwide_enabled", self._read_systemwide_enabled))
|
||||
return page
|
||||
|
||||
def create_bwrap_page(self):
|
||||
|
|
@ -2155,17 +2239,13 @@ class Settings(Page):
|
|||
layout.addLayout(button_layout)
|
||||
|
||||
layout.addStretch()
|
||||
self.load_bwrap_settings()
|
||||
self.load_bwrap_settings(
|
||||
self._prepared_value("bwrap_enabled", self._read_bwrap_enabled))
|
||||
return page
|
||||
|
||||
def load_systemwide_settings(self):
|
||||
enabled = False
|
||||
try:
|
||||
privilege_policy = PolicyController.get('privilege')
|
||||
if privilege_policy is not None:
|
||||
enabled = PolicyController.is_instated(privilege_policy)
|
||||
except Exception:
|
||||
enabled = False
|
||||
def load_systemwide_settings(self, enabled=None):
|
||||
if enabled is None:
|
||||
enabled = self._read_systemwide_enabled()
|
||||
self.systemwide_toggle.setChecked(enabled)
|
||||
if enabled:
|
||||
self.systemwide_status_value.setText("Enabled")
|
||||
|
|
@ -2202,14 +2282,9 @@ class Settings(Page):
|
|||
self.systemwide_status_value.setStyleSheet(
|
||||
f"color: red; font-size: 14px; {self.font_style}")
|
||||
|
||||
def load_bwrap_settings(self):
|
||||
enabled = False
|
||||
try:
|
||||
capability_policy = PolicyController.get('capability')
|
||||
if capability_policy is not None:
|
||||
enabled = PolicyController.is_instated(capability_policy)
|
||||
except Exception:
|
||||
enabled = False
|
||||
def load_bwrap_settings(self, enabled=None):
|
||||
if enabled is None:
|
||||
enabled = self._read_bwrap_enabled()
|
||||
self.bwrap_toggle.setChecked(enabled)
|
||||
if enabled:
|
||||
self.bwrap_status_value.setText("Enabled")
|
||||
|
|
@ -2248,7 +2323,8 @@ class Settings(Page):
|
|||
|
||||
def load_registrations_settings(self) -> None:
|
||||
try:
|
||||
config = self.update_status._load_gui_config()
|
||||
config = self._prepared_value(
|
||||
"gui_config", self.update_status._load_gui_config)
|
||||
if config and "registrations" in config:
|
||||
registrations = config["registrations"]
|
||||
auto_sync = registrations.get("auto_sync_enabled", False)
|
||||
|
|
|
|||
24
gui/v2/workers/page_data_worker.py
Executable file
24
gui/v2/workers/page_data_worker.py
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
import importlib
|
||||
|
||||
from PyQt6.QtCore import QThread, pyqtSignal
|
||||
|
||||
|
||||
class PageDataWorker(QThread):
|
||||
data_ready = pyqtSignal(str, object)
|
||||
failed = pyqtSignal(str, str)
|
||||
|
||||
def __init__(self, name, module_path, class_name, custom_window):
|
||||
super().__init__()
|
||||
self.name = name
|
||||
self.module_path = module_path
|
||||
self.class_name = class_name
|
||||
self.custom_window = custom_window
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
module = importlib.import_module(self.module_path)
|
||||
cls = getattr(module, self.class_name)
|
||||
payload = cls.prepare_data(self.custom_window)
|
||||
self.data_ready.emit(self.name, payload)
|
||||
except Exception as error:
|
||||
self.failed.emit(self.name, f"{type(error).__name__}: {error}")
|
||||
Loading…
Reference in a new issue