import os from PyQt6.QtWidgets import QLabel, QPushButton from PyQt6.QtGui import QPixmap from core.controllers.ClientController import ClientController from gui.v2.ui.pages.Page import Page from gui.v2.workers.worker_thread import WorkerThread class SyncScreen(Page): def __init__(self, page_stack, main_window=None, parent=None): super().__init__("SyncScreen", page_stack, main_window, parent) self.main_window = main_window self.btn_path = main_window.btn_path self.update_status = main_window self.connection_manager = main_window.connection_manager self.is_tor_mode = main_window.is_tor_mode self.heading_label = QLabel( "You're about to fetch data from\nSimplified Privacy.", self) self.heading_label.setGeometry(15, 80, 750, 120) font_style = "font-size: 34px; font-weight: bold; color: white;" if self.custom_window.open_sans_family: font_style += f" font-family: '{self.custom_window.open_sans_family}';" self.heading_label.setStyleSheet(font_style) self.data_description = QLabel( "This data includes what plans, countries,\nbrowsers, and version upgrades are\navailable. As well as coordinating billing.", self) self.data_description.setGeometry(22, 190, 750, 120) font_style = "font-size: 24px; font-weight: bold; color: #ffff00;" if self.custom_window.open_sans_family: font_style += f" font-family: '{self.custom_window.open_sans_family}';" self.data_description.setStyleSheet(font_style) self.instructions = QLabel( "Use the toggle in the bottom right to\ndecide if you want to use Tor or not.\nThen hit \"Next\"", self) self.instructions.setGeometry(22, 345, 750, 120) font_style = "font-size: 28px; font-weight: bold; color: white;" if self.custom_window.open_sans_family: font_style += f" font-family: '{self.custom_window.open_sans_family}';" self.instructions.setStyleSheet(font_style) self.arrow_label = QLabel(self) self.arrow_label.setGeometry(520, 400, 180, 130) arrow_pixmap = QPixmap(os.path.join(self.btn_path, "arrow-down.png")) self.arrow_label.setPixmap(arrow_pixmap) self.arrow_label.raise_() self.button_go.setVisible(True) self.button_back.setVisible(True) self.button_go.clicked.connect(self.perform_sync) self.button_back.clicked.connect(self.go_back) def showEvent(self, event): super().showEvent(event) self.button_go.setVisible(True) self.button_back.setVisible(True) self.button_go.setEnabled(True) self.button_back.setEnabled(True) def go_back(self): self.custom_window.navigator.navigate("menu") def perform_sync(self): if self.connection_manager.is_synced(): self.button_go.setVisible(True) self.button_back.setVisible(True) self.button_go.setEnabled(True) self.button_back.setEnabled(True) self.custom_window.navigator.navigate("protocol") return self.button_go.setEnabled(False) self.button_back.setEnabled(False) self.update_status.update_status('Sync in progress...') if self.main_window.get_current_connection() == 'tor': self.worker_thread = WorkerThread('SYNC_TOR') else: self.worker_thread = WorkerThread('SYNC') self.worker_thread.sync_output.connect(self.update_output) self.worker_thread.start() def update_output(self, available_locations, available_browsers, status, is_tor, locations, all_browsers): if isinstance(all_browsers, bool) and not all_browsers: self.custom_window.navigator.navigate("install_system_package") install_page = self.custom_window.navigator.get_cached("install_system_package") if install_page is not None: install_page.configure( package_name='tor', distro='debian', is_sync=True) self.button_go.setEnabled(True) self.button_back.setEnabled(True) return if status is False: self.button_go.setEnabled(True) self.button_back.setEnabled(True) self.update_status.update_status('An error occurred during sync') return self.update_status.update_status('Sync complete') update_available = ClientController.can_be_updated() if update_available: menu_page = self.find_menu_page() if menu_page is not None: menu_page.on_update_check_finished() self.custom_window.update_values( available_locations, available_browsers, status, is_tor, locations, all_browsers) self.button_go.setEnabled(True) self.button_back.setEnabled(True) self.custom_window.navigator.navigate("protocol") def update_after_sync(self, available_locations, available_browsers, locations, all_browsers=None): self.connection_manager.set_synced(True) available_locations_list = [] available_browsers_list = [] self.connection_manager.store_locations(locations) self.connection_manager.store_browsers(available_browsers) browser_positions = self.generate_grid_positions( len(available_browsers)) location_positions = self.generate_grid_positions( len(available_locations)) for i, location in enumerate(available_locations): available_locations_list.append( (QPushButton, location, location_positions[i])) for i, browser in enumerate(available_browsers): available_browsers_list.append( (QPushButton, browser, browser_positions[i])) location_page = self.find_location_page() hidetor_page = self.find_hidetor_page() protocol_page = self.find_protocol_page() browser_page = self.find_browser_page() if browser_page: browser_page.create_interface_elements(available_browsers_list) if location_page: location_page.create_interface_elements(available_locations_list) if hidetor_page: hidetor_page.create_interface_elements(available_locations_list) if protocol_page: protocol_page.enable_protocol_buttons() menu_page = self.find_menu_page() if menu_page: menu_page.refresh_profiles_data() def generate_grid_positions(self, num_items): positions = [] start_x = 395 start_y = 90 button_width = 185 button_height = 75 h_spacing = 10 v_spacing = 105 for i in range(num_items): col = i % 2 row = i // 2 x = start_x + (col * (button_width + h_spacing)) y = start_y + (row * v_spacing) positions.append((x, y, button_width, button_height)) return positions def find_browser_page(self): return self.custom_window.navigator.get_cached("browser") def find_location_page(self): return self.custom_window.navigator.get_cached("location") def find_hidetor_page(self): return self.custom_window.navigator.get_cached("hidetor") def find_protocol_page(self): return self.custom_window.navigator.get_cached("protocol") def find_menu_page(self): return self.custom_window.navigator.get_cached("menu")