From d66be255d3d83642724bb97378228ba9923d074e Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 24 Aug 2025 17:31:26 +0100 Subject: [PATCH] Added fast reg / auto syncs --- gui/__main__.py | 653 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 633 insertions(+), 20 deletions(-) diff --git a/gui/__main__.py b/gui/__main__.py index 66431f6..c6bf7c1 100644 --- a/gui/__main__.py +++ b/gui/__main__.py @@ -458,8 +458,10 @@ class CustomWindow(QMainWindow): def update_values(self, available_locations, available_browsers, status, is_tor, locations, all_browsers): sync_screen = self.page_stack.findChild(SyncScreen) - if sync_screen: + if status: sync_screen.update_after_sync(available_locations, available_browsers, locations, all_browsers) + else: + self.update_status.update_status('Sync failed. Please try again later.') @@ -893,6 +895,7 @@ class CustomWindow(QMainWindow): IdPage(self.page_stack, self), TorPage(self.page_stack, self), EditorPage(self.page_stack, self), + FastRegistrationPage(self.page_stack, self), Settings(self.page_stack, self), ConnectionPage(self.page_stack, self), SyncScreen(self.page_stack, self)] @@ -1012,7 +1015,7 @@ class CustomWindow(QMainWindow): if isinstance(current_page, MenuPage): self.update_status(None) - if isinstance(previous_page, (ResumePage, EditorPage, Settings)): + if isinstance(previous_page, (ResumePage, EditorPage, Settings, FastRegistrationPage)): current_page.eliminacion() else: @@ -1327,7 +1330,6 @@ class MenuPage(Page): self.create() - def delete_profile(self): self.popup = ConfirmationPopup(self, message="Are you sure you want to\ndelete this profile?", action_button_text="Delete", cancel_button_text="Cancel") self.popup.setWindowModality(Qt.WindowModality.ApplicationModal) @@ -1766,6 +1768,18 @@ class MenuPage(Page): if len(self.profile_info) == 6: self.update_status.update_status('Maximum number of profiles reached!') return + + settings_page = self.page_stack.findChild(Settings) + if settings_page and settings_page.is_fast_registration_enabled(): + if not self.connection_manager.is_synced(): + self.update_status.update_status('Syncing in progress..') + self.update_status.sync() + self.update_status.worker_thread.sync_output.connect(self.on_sync_complete_for_fast_registration) + else: + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(FastRegistrationPage))) + return + + if not self.connection_manager.is_synced(): self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(SyncScreen))) else: @@ -1773,6 +1787,13 @@ class MenuPage(Page): + def on_sync_complete_for_fast_registration(self, available_locations, available_browsers, status, is_tor, locations, all_browsers): + if status: + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(FastRegistrationPage))) + else: + self.update_status.update_status('Sync failed. Please try again later.') + + def change_connect_button(self): profile = ProfileController.get(int(self.reverse_id)) is_connected = self.connection_manager.is_profile_connected(int(self.reverse_id)) @@ -1797,7 +1818,23 @@ class MenuPage(Page): def edit_prof(self): - self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(EditorPage))) + settings_page = self.page_stack.findChild(Settings) + if settings_page and settings_page.is_auto_sync_enabled(): + self.update_status.update_status('Syncing in progress..') + self.update_status.sync() + self.update_status.worker_thread.sync_output.connect(self.on_sync_complete_for_edit_profile) + else: + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(EditorPage))) + + + def on_sync_complete_for_edit_profile(self, available_locations, available_browsers, status, is_tor, locations, all_browsers): + if status: + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(EditorPage))) + else: + self.update_status.update_status('Sync failed. Please try again later.') + + + def settings_gui(self): self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(Settings))) @@ -3250,16 +3287,25 @@ class BrowserPage(Page): @staticmethod def create_browser_button_image(browser_text, btn_path, is_fallback=False): - browser_name, version = browser_text.split()[0], ' '.join(browser_text.split()[1:]) + if ':' in browser_text: + browser_name, version = browser_text.split(':', 1) + else: + browser_name, version = browser_text.split()[0], ' '.join(browser_text.split()[1:]) if is_fallback: base_image = QPixmap(btn_path) else: base_image = QPixmap(os.path.join(btn_path, f"{browser_name}_button.png")) + + if base_image.isNull(): + base_image = QPixmap(185, 75) + base_image.fill(QColor(44, 62, 80)) + painter = QPainter(base_image) - BrowserPage._setup_version_font(painter, version, base_image) - if is_fallback: - BrowserPage._setup_browser_name(painter, browser_name, base_image) - painter.end() + if painter.isActive(): + BrowserPage._setup_version_font(painter, version, base_image) + if is_fallback: + BrowserPage._setup_browser_name(painter, browser_name, base_image) + painter.end() return base_image @staticmethod @@ -4218,20 +4264,38 @@ class EditorPage(Page): prev_button.setVisible(False) next_button.setVisible(False) + def on_sync_complete_for_edit_profile(self, available_locations, available_browsers, status, is_tor, locations, all_browsers): + if status: + self.update_status.update_status('Sync complete.') + self.extraccion() + else: + self.update_status.update_status('Sync failed. Please try again later.') + def show_previous_value(self, key: str, index: int, parameters: dict) -> None: - if len(parameters[key]) > 1: - previous_index = (index - 1) % len(parameters[key]) - previous_value = parameters[key][previous_index] - self.update_temp_value(key, previous_value) + if key == 'browser' or key == 'location': + if not self.connection_manager.is_synced(): + self.update_status.update_status('Syncing in progress..') + self.update_status.sync() + self.update_status.worker_thread.sync_output.connect(self.on_sync_complete_for_edit_profile) + return + + previous_index = (index - 1) % len(parameters[key]) + previous_value = parameters[key][previous_index] + self.update_temp_value(key, previous_value) def show_next_value(self, key: str, index: int, parameters: dict) -> None: - - if len(parameters[key]) > 1: - next_index = (index + 1) % len(parameters[key]) - next_value = parameters[key][next_index] + if key == 'browser' or key == 'location': + if not self.connection_manager.is_synced(): + self.update_status.update_status('Syncing in progress..') + self.update_status.sync() + self.update_status.worker_thread.sync_output.connect(self.on_sync_complete_for_edit_profile) + return + + next_index = (index + 1) % len(parameters[key]) + next_value = parameters[key][next_index] - self.update_temp_value(key, next_value) + self.update_temp_value(key, next_value) def update_temp_value(self, key: str, new_value: str) -> None: selected_profiles_str = ', '.join([f"Profile_{profile['profile_number']}" for profile in self.page_stack.widget(0).selected_profiles]) @@ -4467,6 +4531,7 @@ class Settings(Page): menu_items = [ ("Overview", self.show_account_page), ("Subscriptions", self.show_subscription_page), + ("Registrations", self.show_registrations_page), ("Delete Profile", self.show_delete_page), ("Error Logs", self.show_logs_page) ] @@ -4730,13 +4795,17 @@ class Settings(Page): self.content_layout.setCurrentWidget(self.subscription_page) self.update_button_states(1) + def show_registrations_page(self): + self.content_layout.setCurrentWidget(self.registrations_page) + self.update_button_states(2) + def show_delete_page(self): self.content_layout.setCurrentWidget(self.delete_page) - self.update_button_states(2) + self.update_button_states(3) def show_logs_page(self): self.content_layout.setCurrentWidget(self.logs_page) - self.update_button_states(3) + self.update_button_states(4) def update_button_states(self, active_index): for i, btn in enumerate(self.menu_buttons): @@ -4875,6 +4944,10 @@ class Settings(Page): self.subscription_page = self.create_subscription_page() self.content_layout.addWidget(self.subscription_page) + self.content_layout.removeWidget(self.registrations_page) + self.registrations_page = self.create_registrations_page() + self.content_layout.addWidget(self.registrations_page) + self.content_layout.removeWidget(self.delete_page) self.delete_page = self.create_delete_page() self.content_layout.addWidget(self.delete_page) @@ -5074,11 +5147,13 @@ class Settings(Page): def setup_pages(self): self.account_page = self.create_account_page() self.subscription_page = self.create_subscription_page() + self.registrations_page = self.create_registrations_page() self.logs_page = self.create_logs_page() self.delete_page = self.create_delete_page() self.content_layout.addWidget(self.account_page) self.content_layout.addWidget(self.subscription_page) + self.content_layout.addWidget(self.registrations_page) self.content_layout.addWidget(self.logs_page) self.content_layout.addWidget(self.delete_page) @@ -5158,6 +5233,108 @@ class Settings(Page): logging.error(f"Error saving logging settings: {str(e)}") self.update_status.update_status("Error saving logging settings") + def create_registrations_page(self): + page = QWidget() + layout = QVBoxLayout(page) + layout.setSpacing(20) + layout.setContentsMargins(20, 20, 20, 20) + + title = QLabel("REGISTRATION SETTINGS") + title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}") + layout.addWidget(title) + + registrations_group = QGroupBox("Registration Configuration") + registrations_group.setStyleSheet(f"QGroupBox {{ color: white; padding: 15px; {self.font_style} }}") + registrations_layout = QVBoxLayout(registrations_group) + + self.enable_auto_sync = QCheckBox("Enable auto-sync") + self.enable_auto_sync.setStyleSheet(self.get_checkbox_style()) + registrations_layout.addWidget(self.enable_auto_sync) + + self.enable_fast_registration = QCheckBox("Enable fast registration") + self.enable_fast_registration.setStyleSheet(self.get_checkbox_style()) + registrations_layout.addWidget(self.enable_fast_registration) + + layout.addWidget(registrations_group) + + save_button = QPushButton() + save_button.setFixedSize(75, 46) + save_button.setIcon(QIcon(os.path.join(self.btn_path, f"save.png"))) + save_button.setIconSize(QSize(75, 46)) + save_button.clicked.connect(self.save_registrations_settings) + + button_layout = QHBoxLayout() + button_layout.addStretch() + button_layout.addWidget(save_button) + layout.addLayout(button_layout) + + layout.addStretch() + self.load_registrations_settings() + return page + + def load_registrations_settings(self) -> None: + try: + config = self.update_status._load_gui_config() + if config and "registrations" in config: + self.enable_auto_sync.setChecked(config["registrations"]["auto_sync_enabled"]) + self.enable_fast_registration.setChecked(config["registrations"]["fast_registration_enabled"]) + else: + self.enable_auto_sync.setChecked(False) + self.enable_fast_registration.setChecked(False) + except Exception as e: + logging.error(f"Error loading registration settings: {str(e)}") + self.enable_auto_sync.setChecked(False) + self.enable_fast_registration.setChecked(False) + + def save_registrations_settings(self) -> None: + try: + config = self.update_status._load_gui_config() + if config is None: + config = { + "logging": { + "gui_logging_enabled": True, + "log_level": "INFO" + }, + "registrations": { + "auto_sync_enabled": False, + "fast_registration_enabled": False + } + } + + if "registrations" not in config: + config["registrations"] = {} + + config["registrations"]["auto_sync_enabled"] = self.enable_auto_sync.isChecked() + config["registrations"]["fast_registration_enabled"] = self.enable_fast_registration.isChecked() + + self.update_status._save_gui_config(config) + self.update_status.update_status("Registration settings saved") + + except Exception as e: + logging.error(f"Error saving registration settings: {str(e)}") + self.update_status.update_status("Error saving registration settings") + + def is_auto_sync_enabled(self) -> bool: + try: + config = self.update_status._load_gui_config() + if config and "registrations" in config: + return config["registrations"]["auto_sync_enabled"] + return False + except Exception as e: + logging.error(f"Error checking auto-sync setting: {str(e)}") + return False + + def is_fast_registration_enabled(self) -> bool: + try: + config = self.update_status._load_gui_config() + if config and "registrations" in config: + return config["registrations"]["fast_registration_enabled"] + return False + except Exception as e: + logging.error(f"Error checking fast registration setting: {str(e)}") + return False + + @@ -6374,6 +6551,442 @@ class PaymentDetailsPage(Page): total_hours = duration_month_num * (30 * 24) return total_hours +class FastRegistrationPage(Page): + def __init__(self, page_stack, main_window): + super().__init__("FastRegistration", page_stack, main_window) + self.page_stack = page_stack + self.update_status = main_window + self.connection_manager = main_window.connection_manager + self.labels = [] + self.buttons = [] + self.title.setGeometry(550, 40, 250, 40) + self.title.setText("Fast Registration") + + self.button_apply.setVisible(True) + self.button_apply.clicked.connect(self.create_profile) + + self.button_back.setVisible(True) + try: + self.button_back.clicked.disconnect() + except TypeError: + pass + self.button_back.clicked.connect(self.go_back) + + self.name_handle = QLabel(self) + self.name_handle.setGeometry(110, 70, 400, 30) + self.name_handle.setStyleSheet('color: #cacbcb;') + self.name_handle.setText("Profile Name:") + + self.name = QLineEdit(self) + self.name.setGeometry(265, 70, 190, 30) + self.name.setStyleSheet("color: cyan; border: transparent;") + + self.profile_data = {} + self.selected_values = { + 'protocol': 'wireguard', + 'connection': 'browser-only', + 'location': '', + 'browser': '', + 'resolution': '1024x760' + } + + self.initialize_default_selections() + + def showEvent(self, event): + super().showEvent(event) + self.initialize_default_selections() + self.create_interface_elements() + + def create_interface_elements(self): + for label in self.labels: + label.deleteLater() + self.labels = [] + for button in self.buttons: + button.deleteLater() + self.buttons = [] + + self.create_protocol_section() + self.create_connection_section() + self.create_location_section() + self.create_browser_section() + self.create_resolution_section() + + def create_protocol_section(self): + label = QLabel("Protocol", self) + label.setGeometry(300, 150, 185, 75) + + protocol_image = QPixmap(os.path.join(self.btn_path, f"{self.selected_values['protocol']}_button.png")) + label.setPixmap(protocol_image) + label.setScaledContents(True) + label.show() + self.labels.append(label) + + prev_button = QPushButton(self) + prev_button.setGeometry(265, 150, 30, 75) + prev_button.clicked.connect(lambda: self.show_previous_value('protocol')) + prev_button.show() + icon_path = os.path.join(self.btn_path, "UP_button.png") + icon = QPixmap(icon_path) + transform = QTransform().rotate(180) + rotated_icon = icon.transformed(transform) + prev_button.setIcon(QIcon(rotated_icon)) + prev_button.setIconSize(prev_button.size()) + self.buttons.append(prev_button) + + next_button = QPushButton(self) + next_button.setGeometry(490, 150, 30, 75) + next_button.clicked.connect(lambda: self.show_next_value('protocol')) + next_button.show() + next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png"))) + next_button.setIconSize(next_button.size()) + self.buttons.append(next_button) + + def create_connection_section(self): + label = QLabel("Connection", self) + label.setGeometry(150, 250, 185, 75) + + if self.selected_values['connection']: + connection_image = QPixmap(os.path.join(self.btn_path, f"{self.selected_values['connection']}_button.png")) + if connection_image.isNull(): + fallback_path = os.path.join(self.btn_path, "browser-only_button.png") + connection_image = QPixmap(fallback_path) + else: + connection_image = QPixmap(os.path.join(self.btn_path, "browser-only_button.png")) + + label.setPixmap(connection_image) + label.setScaledContents(True) + label.show() + self.labels.append(label) + + prev_button = QPushButton(self) + prev_button.setGeometry(115, 250, 30, 75) + prev_button.clicked.connect(lambda: self.show_previous_value('connection')) + prev_button.show() + icon_path = os.path.join(self.btn_path, "UP_button.png") + icon = QPixmap(icon_path) + transform = QTransform().rotate(180) + rotated_icon = icon.transformed(transform) + prev_button.setIcon(QIcon(rotated_icon)) + prev_button.setIconSize(prev_button.size()) + self.buttons.append(prev_button) + + next_button = QPushButton(self) + next_button.setGeometry(340, 250, 30, 75) + next_button.clicked.connect(lambda: self.show_next_value('connection')) + next_button.show() + next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png"))) + next_button.setIconSize(next_button.size()) + self.buttons.append(next_button) + + def create_location_section(self): + label = QLabel("Location", self) + label.setGeometry(435, 250, 185, 75) + + if self.selected_values['location']: + image_path = os.path.join(self.btn_path, f"button_{self.selected_values['location']}.png") + location_image = QPixmap(image_path) + if location_image.isNull(): + fallback_path = os.path.join(self.btn_path, "default_location_button.png") + location_image = LocationPage.create_location_button_image(self.selected_values['location'], fallback_path) + else: + location_image = QPixmap(os.path.join(self.btn_path, "default_location_button.png")) + + label.setPixmap(location_image) + label.setScaledContents(True) + label.show() + self.labels.append(label) + + prev_button = QPushButton(self) + prev_button.setGeometry(400, 250, 30, 75) + prev_button.clicked.connect(lambda: self.show_previous_value('location')) + prev_button.show() + icon_path = os.path.join(self.btn_path, "UP_button.png") + icon = QPixmap(icon_path) + transform = QTransform().rotate(180) + rotated_icon = icon.transformed(transform) + prev_button.setIcon(QIcon(rotated_icon)) + prev_button.setIconSize(prev_button.size()) + self.buttons.append(prev_button) + + next_button = QPushButton(self) + next_button.setGeometry(625, 250, 30, 75) + next_button.clicked.connect(lambda: self.show_next_value('location')) + next_button.show() + next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png"))) + next_button.setIconSize(next_button.size()) + self.buttons.append(next_button) + + def create_browser_section(self): + label = QLabel("Browser", self) + label.setGeometry(150, 350, 185, 75) + + if self.selected_values['browser']: + browser_image = BrowserPage.create_browser_button_image(self.selected_values['browser'], self.btn_path) + if browser_image.isNull(): + fallback_path = os.path.join(self.btn_path, "default_browser_button.png") + browser_image = BrowserPage.create_browser_button_image(self.selected_values['browser'], fallback_path, True) + else: + browser_image = QPixmap() + + label.setPixmap(browser_image) + label.setScaledContents(True) + label.show() + self.labels.append(label) + + prev_button = QPushButton(self) + prev_button.setGeometry(115, 350, 30, 75) + prev_button.clicked.connect(lambda: self.show_previous_value('browser')) + prev_button.show() + icon_path = os.path.join(self.btn_path, "UP_button.png") + icon = QPixmap(icon_path) + transform = QTransform().rotate(180) + rotated_icon = icon.transformed(transform) + prev_button.setIcon(QIcon(rotated_icon)) + prev_button.setIconSize(prev_button.size()) + self.buttons.append(prev_button) + + next_button = QPushButton(self) + next_button.setGeometry(340, 350, 30, 75) + next_button.clicked.connect(lambda: self.show_next_value('browser')) + next_button.show() + next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png"))) + next_button.setIconSize(next_button.size()) + self.buttons.append(next_button) + + def create_resolution_section(self): + label = QLabel("Resolution", self) + label.setGeometry(435, 350, 185, 75) + screen_page = self.page_stack.findChild(ScreenPage) + if self.selected_values['resolution']: + + resolution_image = screen_page.create_resolution_button_image(self.selected_values['resolution']) + else: + resolution_image = screen_page.create_resolution_button_image("1024x760") + + label.setPixmap(resolution_image) + label.setScaledContents(True) + label.show() + self.labels.append(label) + + prev_button = QPushButton(self) + prev_button.setGeometry(400, 350, 30, 75) + prev_button.clicked.connect(lambda: self.show_previous_value('resolution')) + prev_button.show() + icon_path = os.path.join(self.btn_path, "UP_button.png") + icon = QPixmap(icon_path) + transform = QTransform().rotate(180) + rotated_icon = icon.transformed(transform) + prev_button.setIcon(QIcon(rotated_icon)) + prev_button.setIconSize(prev_button.size()) + self.buttons.append(prev_button) + + next_button = QPushButton(self) + next_button.setGeometry(625, 350, 30, 75) + next_button.clicked.connect(lambda: self.show_next_value('resolution')) + next_button.show() + next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png"))) + next_button.setIconSize(next_button.size()) + self.buttons.append(next_button) + + def show_previous_value(self, key): + if key == 'protocol': + protocols = ['wireguard', 'hidetor'] + current_index = protocols.index(self.selected_values[key]) + previous_index = (current_index - 1) % len(protocols) + self.selected_values[key] = protocols[previous_index] + if self.selected_values[key] == 'wireguard': + self.selected_values['connection'] = 'browser-only' + else: + self.selected_values['connection'] = 'tor' + elif key == 'connection': + if self.selected_values['protocol'] == 'wireguard': + connections = ['browser-only', 'system-wide'] + else: + connections = ['tor', 'just proxy'] + current_index = connections.index(self.selected_values[key]) + previous_index = (current_index - 1) % len(connections) + self.selected_values[key] = connections[previous_index] + elif key == 'location': + locations = self.connection_manager.get_location_list() + if locations and self.selected_values[key] in locations: + current_index = locations.index(self.selected_values[key]) + previous_index = (current_index - 1) % len(locations) + self.selected_values[key] = locations[previous_index] + elif locations: + self.selected_values[key] = locations[0] + elif key == 'browser': + browsers = self.connection_manager.get_browser_list() + if browsers and self.selected_values[key] in browsers: + current_index = browsers.index(self.selected_values[key]) + previous_index = (current_index - 1) % len(browsers) + self.selected_values[key] = browsers[previous_index] + elif browsers: + self.selected_values[key] = browsers[0] + elif key == 'resolution': + resolutions = ['800x600', '1024x760', '1152x1080', '1280x1024', '1920x1080', '2560x1440', '2560x1600', '1920x1440', '1792x1344', '2048x1152'] + current_index = resolutions.index(self.selected_values[key]) + previous_index = (current_index - 1) % len(resolutions) + self.selected_values[key] = resolutions[previous_index] + + self.create_interface_elements() + + def show_next_value(self, key): + if key == 'protocol': + protocols = ['wireguard', 'hidetor'] + current_index = protocols.index(self.selected_values[key]) + next_index = (current_index + 1) % len(protocols) + self.selected_values[key] = protocols[next_index] + if self.selected_values[key] == 'wireguard': + self.selected_values['connection'] = 'browser-only' + else: + self.selected_values['connection'] = 'tor' + elif key == 'connection': + if self.selected_values['protocol'] == 'wireguard': + connections = ['browser-only', 'system-wide'] + else: + connections = ['tor', 'just proxy'] + current_index = connections.index(self.selected_values[key]) + next_index = (current_index + 1) % len(connections) + self.selected_values[key] = connections[next_index] + elif key == 'location': + locations = self.connection_manager.get_location_list() + if locations and self.selected_values[key] in locations: + current_index = locations.index(self.selected_values[key]) + next_index = (current_index + 1) % len(locations) + self.selected_values[key] = locations[next_index] + elif locations: + self.selected_values[key] = locations[0] + elif key == 'browser': + browsers = self.connection_manager.get_browser_list() + if browsers and self.selected_values[key] in browsers: + current_index = browsers.index(self.selected_values[key]) + next_index = (current_index + 1) % len(browsers) + self.selected_values[key] = browsers[next_index] + elif browsers: + self.selected_values[key] = browsers[0] + elif key == 'resolution': + resolutions = ['800x600', '1024x760', '1152x1080', '1280x1024', '1920x1080', '2560x1440', '2560x1600', '1920x1440', '1792x1344', '2048x1152'] + current_index = resolutions.index(self.selected_values[key]) + next_index = (current_index + 1) % len(resolutions) + self.selected_values[key] = resolutions[next_index] + + self.create_interface_elements() + + def go_back(self): + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage))) + + def create_profile(self): + profile_name = self.name.text() + if not profile_name: + self.update_status.update_status('Please enter a profile name') + return + + if not self.selected_values['location']: + self.update_status.update_status('Please select a location') + return + + if self.selected_values['connection'] != 'system-wide' and not self.selected_values['browser']: + self.update_status.update_status('Please select a browser') + return + + profile_data = { + 'name': profile_name, + 'protocol': self.selected_values['protocol'], + 'connection': self.selected_values['connection'], + 'location': self.selected_values['location'], + 'browser': self.selected_values['browser'], + 'resolution': self.selected_values['resolution'] + } + + self.profile_data = profile_data + self.update_status.write_data(profile_data) + + resume_page = self.find_resume_page() + if resume_page: + if self.selected_values['protocol'] == 'wireguard': + self.create_wireguard_profile(profile_data) + else: + self.create_tor_profile(profile_data) + + self.go_back() + + def create_wireguard_profile(self, profile_data): + location_info = self.connection_manager.get_location_info(profile_data['location']) + if not location_info: + self.update_status.update_status('Invalid location selected') + return + + profile_id = self.get_next_available_profile_id() + profile_data_for_resume = { + 'id': profile_id, + 'name': profile_data['name'], + 'country_code': location_info.country_code, + 'code': location_info.code, + 'application': profile_data['browser'], + 'connection_type': 'wireguard', + 'resolution': profile_data['resolution'], + } + + resume_page = self.find_resume_page() + if resume_page: + resume_page.handle_core_action_create_profile('CREATE_SESSION_PROFILE', profile_data_for_resume, 'session') + + def create_tor_profile(self, profile_data): + location_info = self.connection_manager.get_location_info(profile_data['location']) + if not location_info: + self.update_status.update_status('Invalid location selected') + return + + connection_type = 'tor' if profile_data['connection'] == 'tor' else 'system' + + profile_id = self.get_next_available_profile_id() + profile_data_for_resume = { + 'id': profile_id, + 'name': profile_data['name'], + 'country_code': location_info.country_code, + 'code': location_info.code, + 'application': profile_data['browser'], + 'connection_type': connection_type, + 'resolution': profile_data['resolution'], + } + + resume_page = self.find_resume_page() + if resume_page: + resume_page.handle_core_action_create_profile('CREATE_SESSION_PROFILE', profile_data_for_resume, 'session') + + + + def find_resume_page(self): + for i in range(self.page_stack.count()): + page = self.page_stack.widget(i) + if isinstance(page, ResumePage): + return page + return None + + def initialize_default_selections(self): + if not self.selected_values['location']: + locations = self.connection_manager.get_location_list() + if locations: + self.selected_values['location'] = locations[0] + + if not self.selected_values['browser']: + browsers = self.connection_manager.get_browser_list() + if browsers: + self.selected_values['browser'] = browsers[0] + + def get_next_available_profile_id(self) -> int: + profiles = ProfileController.get_all() + if not profiles: + return 1 + + existing_ids = sorted(profiles.keys()) + + for i in range(1, max(existing_ids) + 2): + if i not in existing_ids: + return i + + return 1 + class QRCodeDialog(QDialog): def __init__(self, address_text, full_amount, currency_type=None, parent=None): super().__init__(parent)