463 lines
21 KiB
Python
Executable file
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
|