hydraveil-gui/gui/v2/ui/pages/resume_page.py
2026-06-13 16:19:11 -04:00

463 lines
21 KiB
Python
Executable file

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