import os from PyQt6.QtWidgets import ( QLabel, QPushButton, QButtonGroup, QLineEdit, QTextEdit, QFrame ) from PyQt6.QtGui import QPixmap, QIcon from PyQt6.QtCore import Qt, QSize from PyQt6 import QtCore, QtGui from core.controllers.ProfileController import ProfileController from gui.v2.actions.profile_order import append_profile_to_visual_order from gui.v2.ui.pages.Page import Page from gui.v2.ui.pages.location_page import LocationPage from gui.v2.ui.pages.screen_page import ScreenPage class ResumePage(Page): def __init__(self, page_stack, main_window=None, parent=None): super().__init__("Resume", page_stack, main_window, parent) self.update_status = main_window self.connection_manager = main_window.connection_manager self.btn_path = main_window.btn_path self.labels_creados = [] self.additional_labels = [] self.button_go.clicked.connect(self.copy_profile) self.button_back.setVisible(True) self.title.setGeometry(585, 40, 185, 40) self.title.setText("Profile Summary") self.display.setGeometry(QtCore.QRect(5, 50, 580, 435)) self.buttonGroup = QButtonGroup(self) self.button_back.clicked.connect(self.reverse) self.create_arrow() self.create_interface_elements() def reverse(self): if self.connection_type == "system-wide": self.custom_window.navigator.navigate("location") else: self.custom_window.navigator.navigate("screen") def show_location_verification(self, location_icon_name): from gui.v2.ui.pages.location_verification_page import LocationVerificationPage verification_page = LocationVerificationPage( self.page_stack, self.update_status, location_icon_name, self) self.page_stack.addWidget(verification_page) self.page_stack.setCurrentIndex( self.page_stack.indexOf(verification_page)) def create_arrow(self): self.arrow_label = QLabel(self) self.arrow_label.setGeometry(400, 115, 200, 200) arrow_pixmap = QPixmap(os.path.join(self.btn_path, "arrow.png")) self.arrow_label.setPixmap(arrow_pixmap) self.arrow_label.setScaledContents(True) self.arrow_label.raise_() def showEvent(self, event): super().showEvent(event) self.arrow_label.show() self.arrow_label.raise_() def create_interface_elements(self): for j, (object_type, icon_name, geometry) in enumerate([ (QLineEdit, None, (130, 73, 300, 24)), (QLabel, None, (0, 0, 0, 0)) ]): if object_type == QLabel: label = object_type(self) label.setGeometry(*geometry) icon_path = os.path.join( self.btn_path, f"{icon_name}_button.png") if os.path.exists(icon_path): label.setPixmap(QPixmap(icon_path)) locations = self.connection_manager.get_location_info( icon_name) provider = locations.operator.name if locations and hasattr( locations, 'operator') else None if label.pixmap().isNull(): if locations and hasattr(locations, 'country_name'): location_name = locations.country_name label.setPixmap(LocationPage.create_location_button_image( location_name, os.path.join(self.btn_path, "default_location_button.png"), provider)) else: label.setPixmap(LocationPage.create_location_button_image( '', os.path.join(self.btn_path, "default_location_button.png"), provider)) else: if locations and hasattr(locations, 'country_name'): label.setPixmap(LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', os.path.join( self.btn_path, "default_location_button.png"), provider, icon_path)) else: label.setPixmap(LocationPage.create_location_button_image('', os.path.join( self.btn_path, "default_location_button.png"), provider, icon_path)) elif object_type == QLineEdit: self.line_edit = object_type(self) self.line_edit.setGeometry(*geometry) self.line_edit.setMaxLength(13) self.line_edit.textChanged.connect( self.toggle_button_visibility) self.line_edit.setStyleSheet( "background-color: transparent; border: none; color: cyan;") self.line_edit.setPlaceholderText("Enter profile name") self.line_edit.setAlignment(Qt.AlignmentFlag.AlignCenter) self.create() def create(self): for label in self.additional_labels: label.deleteLater() self.additional_labels.clear() profile_1 = self.update_status.read_data() self.connection_type = profile_1.get("connection", "") connection_exists = 'connection' in profile_1 if connection_exists and profile_1['connection'] not in ["tor", "just proxy"]: items = ["protocol", "connection", "location", "browser", "dimentions"] initial_y = 90 label_height = 80 elif connection_exists: items = ["protocol", "connection", "location", "browser", "dimentions"] initial_y = 90 label_height = 80 else: items = ["protocol", "location", "browser", "dimentions"] initial_y = 90 label_height = 105 for i, item in enumerate(items): text = profile_1.get(item, "") if text: if item == 'browser': from gui.v2.ui.pages.browser_page import BrowserPage base_image = BrowserPage.create_browser_button_image( text, self.btn_path) geometry = (585, initial_y + i * label_height, 185, 75) parent_label = QLabel(self) parent_label.setGeometry(*geometry) parent_label.setPixmap(base_image) if parent_label.pixmap().isNull(): fallback_path = os.path.join( self.btn_path, "default_browser_button.png") base_image = BrowserPage.create_browser_button_image( text, fallback_path, True) parent_label.setPixmap(base_image) parent_label.show() self.labels_creados.append(parent_label) elif item == 'location': icon_path = os.path.join( self.btn_path, f"button_{text}.png") geometry = (585, initial_y + i * label_height, 185, 75) parent_label = QPushButton(self) parent_label.setGeometry(*geometry) parent_label.setFlat(True) parent_label.setStyleSheet( "background: transparent; border: none;") location_pixmap = QPixmap(icon_path) locations = self.connection_manager.get_location_info(text) provider = locations.operator.name if locations and hasattr( locations, 'operator') else None fallback_path = os.path.join( self.btn_path, "default_location_button.png") if location_pixmap.isNull(): if locations and hasattr(locations, 'country_name'): location_name = locations.country_name base_image = LocationPage.create_location_button_image( location_name, fallback_path, provider) parent_label.setIcon(QIcon(base_image)) else: base_image = LocationPage.create_location_button_image( '', fallback_path, provider) parent_label.setIcon(QIcon(base_image)) else: if locations and hasattr(locations, 'country_name'): base_image = LocationPage.create_location_button_image( f'{locations.country_code}_{locations.code}', fallback_path, provider, icon_path) parent_label.setIcon(QIcon(base_image)) else: base_image = LocationPage.create_location_button_image( '', fallback_path, provider, icon_path) parent_label.setIcon(QIcon(base_image)) parent_label.setIconSize(QSize(185, 75)) parent_label.location_icon_name = text parent_label.setCursor( QtCore.Qt.CursorShape.PointingHandCursor) parent_label.clicked.connect( lambda checked, loc=text: self.show_location_verification(loc)) parent_label.show() self.labels_creados.append(parent_label) elif item == 'dimentions': base_image = ScreenPage.create_resolution_button_image( self, text) geometry = (585, initial_y + i * label_height, 185, 75) parent_label = QLabel(self) parent_label.setGeometry(*geometry) parent_label.setPixmap(base_image) parent_label.show() self.labels_creados.append(parent_label) else: icon_path = os.path.join( self.btn_path, f"{text}_button.png") geometry = (585, initial_y + i * label_height, 185, 75) parent_label = QLabel(self) parent_label.setGeometry(*geometry) parent_label.setPixmap(QPixmap(icon_path)) parent_label.show() self.labels_creados.append(parent_label) location_text = profile_1.get("location", "") location_info = self.connection_manager.get_location_info( location_text) operator_name = "" if location_info and hasattr(location_info, 'operator') and location_info.operator: operator_name = location_info.operator.name or "" if operator_name != 'Simplified Privacy' and operator_name != "": text_color = "white" if self.connection_type != "system-wide": text_color = "black" image_name = "browser only.png" image_path = os.path.join(self.btn_path, image_name) label_background = QLabel(self) label_background.setGeometry(10, 50, 535, 460) label_background.setPixmap(QPixmap(image_path)) label_background.setScaledContents(True) label_background.show() label_background.lower() self.labels_creados.append(label_background) l_img = QLabel(self) l_img.setGeometry(30, 135, 150, 150) pixmap_loc = QPixmap(os.path.join( self.btn_path, f"icon_{location_text}.png")) l_img.setPixmap(pixmap_loc) l_img.setScaledContents(True) l_img.show() self.labels_creados.append(l_img) l_name = f"{location_info.country_name}, {location_info.name}" if location_info and hasattr( location_info, 'country_name') else "" o_name = operator_name n_key = location_info.operator.nostr_public_key if location_info and hasattr( location_info, 'operator') and location_info.operator else "" info_txt = QTextEdit(self) info_txt.setGeometry(190, 130, 310, 250) info_txt.setReadOnly(True) info_txt.setFrameStyle(QFrame.Shape.NoFrame) info_txt.setStyleSheet( f"background: transparent; border: none; color: {text_color}; font-size: 19px;") info_txt.setVerticalScrollBarPolicy( Qt.ScrollBarPolicy.ScrollBarAlwaysOff) info_txt.setHorizontalScrollBarPolicy( Qt.ScrollBarPolicy.ScrollBarAlwaysOff) info_txt.setWordWrapMode( QtGui.QTextOption.WrapMode.WrapAtWordBoundaryOrAnywhere) info_txt.setText(f"Location: {l_name}\n\nOperator: {o_name}") info_txt.show() self.labels_creados.append(info_txt) nostr_txt = QTextEdit(self) nostr_txt.setGeometry(30, 310, 480, 170) nostr_txt.setReadOnly(True) nostr_txt.setFrameStyle(QFrame.Shape.NoFrame) nostr_txt.setStyleSheet( f"background: transparent; border: none; color: {text_color}; font-size: 21px;") nostr_txt.setVerticalScrollBarPolicy( Qt.ScrollBarPolicy.ScrollBarAlwaysOff) nostr_txt.setHorizontalScrollBarPolicy( Qt.ScrollBarPolicy.ScrollBarAlwaysOff) nostr_txt.setWordWrapMode( QtGui.QTextOption.WrapMode.WrapAnywhere) nostr_txt.setText(f"Nostr: {n_key}") nostr_txt.show() self.labels_creados.append(nostr_txt) elif connection_exists: if profile_1.get("connection", "") == "system-wide": image_path = os.path.join( self.btn_path, f"wireguard_{profile_1.get('location', '')}.png") main_label = QLabel(self) main_label.setGeometry(10, 130, 500, 375) main_label.setPixmap(QPixmap(image_path)) main_label.setScaledContents(True) main_label.show() self.labels_creados.append(main_label) if profile_1.get("connection", "") == "just proxy": image_path = os.path.join( self.btn_path, f"icon_{profile_1.get('location', '')}.png") main_label = QLabel(self) main_label.setGeometry(10, 105, 530, 398) main_label.setPixmap(QPixmap(image_path)) main_label.setScaledContents(True) main_label.show() self.labels_creados.append(main_label) if profile_1.get("connection", "") == "tor": image_path = os.path.join( self.btn_path, f"hdtor_{profile_1.get('location', '')}.png") main_label = QLabel(self) main_label.setGeometry(10, 105, 530, 398) main_label.setPixmap(QPixmap(image_path)) main_label.setScaledContents(True) main_label.show() self.labels_creados.append(main_label) if profile_1.get("connection", "") == "browser-only": image_name = "browser only.png" image_path = os.path.join(self.btn_path, image_name) label_background = QLabel(self) label_background.setGeometry(10, 50, 535, 460) label_background.setPixmap(QPixmap(image_path)) label_background.setScaledContents(True) label_background.show() label_background.lower() self.labels_creados.append(label_background) image_path = os.path.join( self.btn_path, f"wireguard_{profile_1.get('location', '')}.png") main_label = QLabel(self) main_label.setGeometry(10, 130, 500, 375) main_label.setPixmap(QPixmap(image_path)) main_label.setScaledContents(True) main_label.show() self.labels_creados.append(main_label) else: image_path = os.path.join( self.btn_path, f"icon_{profile_1.get('location', '')}.png") main_label = QLabel(self) main_label.setGeometry(10, 130, 500, 375) main_label.setPixmap(QPixmap(image_path)) main_label.setScaledContents(True) main_label.show() self.labels_creados.append(main_label) if hasattr(self, 'arrow_label'): self.arrow_label.raise_() def toggle_button_visibility(self): self.button_go.setVisible(bool(self.line_edit.text())) def find_menu_page(self): return self.custom_window.navigator.get_cached("menu") def copy_profile(self): profile_name = self.line_edit.text() menu_page = self.find_menu_page() if menu_page: number_of_profiles = menu_page.number_of_profiles profile_data = self.update_status.read_data() required_fields = [profile_data.get("protocol"), profile_name] if not all(required_fields): print("Error: Some required fields are empty!") return profile_data["name"] = profile_name profile_data["visible"] = "yes" profiles = ProfileController.get_all() profile_id = self.get_next_available_id(profiles) new_profile = profile_data self.create_core_profiles(new_profile, profile_id) if ProfileController.get(profile_id) is not None: append_profile_to_visual_order( getattr(self.update_status, 'gui_config_file', None), profile_id, profiles.keys()) main = self.update_status if hasattr(main, 'navigate_after_profile_created'): main.navigate_after_profile_created() else: self.custom_window.navigator.navigate("menu") self.update_status.clear_data() self.line_edit.clear() self.display.clear() self.button_go.setVisible(False) def get_next_available_id(self, profiles: dict) -> int: 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 None def create_core_profiles(self, profile, id): if profile.get('connection') != 'system-wide': browser_info = profile.get('browser', '').split() if len(browser_info) < 2: self.update_status.update_status( 'Application version not supported') return application = f"{browser_info[0].lower()}:{browser_info[1]}" else: application = '' parts = profile.get('location').split('_') country_code = parts[0] location_code = parts[1] if profile.get('protocol') == 'wireguard': connection_type = 'wireguard' elif profile.get('protocol') == 'hidetor' or profile.get('protocol') == 'residential': if profile.get('connection') == 'tor': connection_type = 'tor' elif profile.get('connection') == 'just proxy': connection_type = 'system' else: self.update_status.update_status('Connection type not supported') return profile_data = { 'id': int(id), 'name': profile.get('name'), 'country_code': country_code, 'code': location_code, 'application': application, 'connection_type': connection_type, 'resolution': profile.get('dimentions', ''), } profile_type = 'system' if profile.get( 'connection') == 'system-wide' else 'session' action = f'CREATE_{profile_type.upper()}_PROFILE' self.handle_core_action_create_profile( action, profile_data, profile_type) def eliminacion(self): for label in self.labels_creados: label.deleteLater() self.labels_creados = [] self.create() if hasattr(self, 'arrow_label'): self.arrow_label.show() self.arrow_label.raise_() def handle_core_action_create_profile(self, action, profile_data=None, profile_type=None): from gui.v2.workers.worker_thread import WorkerThread self.worker_thread = WorkerThread(action, profile_data, profile_type) self.worker_thread.text_output.connect(self.update_output) self.worker_thread.start() self.worker_thread.wait() def update_output(self, text): self.update_status.update_status(text) def on_profile_creation(self, result): if self.worker_thread: self.worker_thread.quit() self.worker_thread.wait() self.worker_thread = None