300 lines
11 KiB
Python
300 lines
11 KiB
Python
from PyQt5.QtCore import Qt, QTimer, QDir, QSize, QDateTime, QRect, QThread, pyqtSignal, QMutex, QObject, QEvent
|
|
from PyQt5.QtGui import (QImage, QPixmap, QIcon, QColor, QKeySequence, QPainter,
|
|
QPen, QBrush)
|
|
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
|
|
QWidget, QLabel, QPushButton, QComboBox, QSpinBox,
|
|
QFileDialog, QMessageBox, QMenu, QAction, QActionGroup, QGridLayout, QGroupBox,
|
|
QDockWidget, QScrollArea, QToolButton, QDialog,
|
|
QShortcut, QListWidget, QFormLayout, QLineEdit,
|
|
QCheckBox, QTabWidget, QListWidgetItem, QSplitter,
|
|
QProgressBar, QSizePolicy)
|
|
import todopackage.todo as todo
|
|
from utility import getpath
|
|
import cv2
|
|
import sys
|
|
import psutil
|
|
import numpy as np
|
|
import requests
|
|
from initqt import initQT
|
|
|
|
class AboutWindow(QDialog):
|
|
def __init__(self, parent=None):
|
|
global todo_style_path
|
|
super().__init__(parent)
|
|
self.setWindowTitle("About Multi-Camera YOLO Detection")
|
|
self.setWindowIcon(QIcon.fromTheme("help-about"))
|
|
self.resize(450, 420)
|
|
|
|
self.setWindowModality(Qt.ApplicationModal)
|
|
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
|
|
|
|
layout = QVBoxLayout()
|
|
layout.setAlignment(Qt.AlignTop)
|
|
layout.setSpacing(20)
|
|
|
|
# App icon
|
|
icon_label = QLabel()
|
|
icon_label.setPixmap(QIcon.fromTheme("camera-web").pixmap(64, 64))
|
|
icon_label.setAlignment(Qt.AlignCenter)
|
|
layout.addWidget(icon_label)
|
|
|
|
# Title
|
|
title_label = QLabel("PySec")
|
|
title_label.setStyleSheet("font-size: 18px; font-weight: bold;")
|
|
title_label.setAlignment(Qt.AlignCenter)
|
|
layout.addWidget(title_label)
|
|
|
|
# Version label
|
|
version_label = QLabel("Version 1.0")
|
|
version_label.setAlignment(Qt.AlignCenter)
|
|
layout.addWidget(version_label)
|
|
|
|
# Get system info
|
|
info = self.get_system_info()
|
|
self.important_keys = ["Python", "OpenCV", "Memory", "CUDA"]
|
|
self.full_labels = {}
|
|
|
|
# === System Info Group ===
|
|
self.sysinfo_box = QGroupBox()
|
|
sysinfo_main_layout = QVBoxLayout()
|
|
sysinfo_main_layout.setContentsMargins(8, 8, 8, 8)
|
|
|
|
# Header layout: title + triangle button
|
|
header_layout = QHBoxLayout()
|
|
header_label = QLabel("System Information")
|
|
header_label.setStyleSheet("font-weight: bold;")
|
|
header_layout.addWidget(header_label)
|
|
|
|
header_layout.addStretch()
|
|
|
|
self.toggle_btn = QToolButton()
|
|
self.toggle_btn.setText("▶")
|
|
self.toggle_btn.setCheckable(True)
|
|
self.toggle_btn.setChecked(False)
|
|
toggle_btn_style = getpath.resource_path("styling/togglebtnabout.qss")
|
|
try:
|
|
with open(toggle_btn_style, "r") as tgbstyle:
|
|
self.toggle_btn.setStyleSheet(tgbstyle.read())
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
# Debug shit
|
|
#print("i did shit")
|
|
|
|
self.toggle_btn.toggled.connect(self.toggle_expand)
|
|
header_layout.addWidget(self.toggle_btn)
|
|
|
|
sysinfo_main_layout.addLayout(header_layout)
|
|
|
|
# Details layout
|
|
self.sysinfo_layout = QVBoxLayout()
|
|
self.sysinfo_layout.setSpacing(5)
|
|
|
|
for key, value in info.items():
|
|
if key == "MemoryGB":
|
|
continue
|
|
|
|
label = QLabel(f"{key}: {value}")
|
|
self.style_label(label, key, value)
|
|
self.sysinfo_layout.addWidget(label)
|
|
self.full_labels[key] = label
|
|
|
|
if key not in self.important_keys:
|
|
label.setVisible(False)
|
|
|
|
sysinfo_main_layout.addLayout(self.sysinfo_layout)
|
|
self.sysinfo_box.setLayout(sysinfo_main_layout)
|
|
layout.addWidget(self.sysinfo_box)
|
|
|
|
# Close button
|
|
close_btn = QPushButton("Close")
|
|
close_btn.clicked.connect(self.accept)
|
|
close_btn.setFixedWidth(100)
|
|
layout.addWidget(close_btn, alignment=Qt.AlignCenter)
|
|
|
|
# Set Styling for About Section
|
|
style_file = getpath.resource_path("styling/about.qss")
|
|
try:
|
|
with open(style_file, "r") as aboutstyle:
|
|
self.setStyleSheet(aboutstyle.read())
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
self.setLayout(layout)
|
|
|
|
# Todo Label Shit
|
|
self.todo_obj = todo
|
|
todo_text = self.get_todo_text()
|
|
todo_label = QLabel(f"<pre>{todo_text}</pre>")
|
|
todo_label.setWordWrap(True)
|
|
todo_label.setAlignment(Qt.AlignLeft)
|
|
|
|
# TODO: Fix this xD ; Fixing a TODO lol
|
|
try:
|
|
todo_style_path = getpath.resource_path("styling/todostyle.qss")
|
|
with open(todo_style_path, "r") as tdf:
|
|
todo_label.setStyleSheet(tdf.read())
|
|
# here we have our wonderfull fix
|
|
if True == True:
|
|
todo_label.setStyleSheet("color: #f7ef02; font-style: italic;")
|
|
else:
|
|
pass
|
|
except FileNotFoundError:
|
|
print(f"Missing a Style File! => {todo_style_path}")
|
|
pass
|
|
|
|
# Create the labels for the fucking trodo ass shit ?
|
|
self.todo_archive_object = todo
|
|
todo_archive_text = self.get_archive_text()
|
|
todo_archive_label = QLabel(f"<pre>{todo_archive_text}</pre>")
|
|
todo_archive_label.setWordWrap(True)
|
|
todo_archive_label.setAlignment(Qt.AlignLeft)
|
|
todo_archive_label.setStyleSheet("color: #02d1fa ;font-style: italic;")
|
|
|
|
self.info_obj = todo
|
|
info_text = self.get_info_text()
|
|
info_label = QLabel(f"<pre>{info_text}</pre>")
|
|
info_label.setWordWrap(True)
|
|
info_label.setAlignment(Qt.AlignCenter)
|
|
info_label.setStyleSheet("color: #2ecc71 ; font-style: italic;")
|
|
|
|
self.camobj = todo
|
|
cam_text = self.get_cam_text()
|
|
cam_label = QLabel(f"<pre>{cam_text}</pre>")
|
|
cam_label.setWordWrap(True)
|
|
cam_label.setAlignment(Qt.AlignCenter)
|
|
cam_label.setStyleSheet("color: #ffffff; font-style: italic;")
|
|
|
|
if True == True:
|
|
layout.addWidget(info_label)
|
|
layout.addWidget(todo_label)
|
|
layout.addWidget(todo_archive_label)
|
|
layout.addWidget(cam_label)
|
|
else:
|
|
pass
|
|
|
|
def toggle_expand(self, checked):
|
|
for key, label in self.full_labels.items():
|
|
if key not in self.important_keys:
|
|
label.setVisible(checked)
|
|
self.toggle_btn.setText("▼" if checked else "▶")
|
|
|
|
def style_label(self, label, key, value):
|
|
if key == "Python":
|
|
label.setStyleSheet("color: #7FDBFF;")
|
|
elif key == "OpenCV":
|
|
label.setStyleSheet("color: #FF851B;")
|
|
elif key == "CUDA":
|
|
label.setStyleSheet("color: green;" if value == "Yes" else "color: red;")
|
|
elif key == "NumPy":
|
|
label.setStyleSheet("color: #B10DC9;")
|
|
elif key == "Requests":
|
|
label.setStyleSheet("color: #0074D9;")
|
|
elif key == "Memory":
|
|
try:
|
|
ram = int(value.split()[0])
|
|
if ram < 8:
|
|
label.setStyleSheet("color: red;")
|
|
elif ram < 16:
|
|
label.setStyleSheet("color: yellow;")
|
|
elif ram < 32:
|
|
label.setStyleSheet("color: lightgreen;")
|
|
else:
|
|
label.setStyleSheet("color: #90EE90;")
|
|
except:
|
|
label.setStyleSheet("color: gray;")
|
|
elif key == "CPU Usage":
|
|
try:
|
|
usage = float(value.strip('%'))
|
|
if usage > 80:
|
|
label.setStyleSheet("color: red;")
|
|
elif usage > 50:
|
|
label.setStyleSheet("color: yellow;")
|
|
else:
|
|
label.setStyleSheet("color: lightgreen;")
|
|
except:
|
|
label.setStyleSheet("color: gray;")
|
|
elif key in ("CPU Cores", "Logical CPUs"):
|
|
label.setStyleSheet("color: lightgreen;")
|
|
elif key in ("CPU", "Architecture", "OS"):
|
|
label.setStyleSheet("color: lightgray;")
|
|
else:
|
|
label.setStyleSheet("color: #DDD;")
|
|
|
|
def get_system_info(self):
|
|
import platform
|
|
|
|
info = {}
|
|
info['Python'] = sys.version.split()[0]
|
|
info['OS'] = f"{platform.system()} {platform.release()}"
|
|
info['Architecture'] = platform.machine()
|
|
info['OpenCV'] = cv2.__version__
|
|
info['CUDA'] = "Yes" if cv2.cuda.getCudaEnabledDeviceCount() > 0 else "No"
|
|
info['NumPy'] = np.__version__
|
|
info['Requests'] = requests.__version__
|
|
|
|
# If we are on Linux we display the QTVAR
|
|
if platform.system() == "Linux":
|
|
info["XDG_ENVIROMENT_TYPE "] = initQT.getenv(self) # get the stupid env var of qt
|
|
else:
|
|
pass
|
|
|
|
mem = psutil.virtual_memory()
|
|
info['MemoryGB'] = mem.total // (1024 ** 3)
|
|
info['Memory'] = f"{info['MemoryGB']} GB RAM"
|
|
|
|
info['CPU Cores'] = psutil.cpu_count(logical=False)
|
|
info['Logical CPUs'] = psutil.cpu_count(logical=True)
|
|
info['CPU Usage'] = f"{psutil.cpu_percent()}%"
|
|
|
|
try:
|
|
if sys.platform == "win32":
|
|
info['CPU'] = platform.processor()
|
|
elif sys.platform == "linux":
|
|
info['CPU'] = subprocess.check_output("lscpu", shell=True).decode().split("\n")[0]
|
|
elif sys.platform == "darwin":
|
|
info['CPU'] = subprocess.check_output(["sysctl", "-n", "machdep.cpu.brand_string"]).decode().strip()
|
|
except Exception:
|
|
info['CPU'] = "Unknown"
|
|
|
|
return info
|
|
|
|
def get_todo_text(self):
|
|
try:
|
|
todo_text = self.todo_obj.todo.gettodo()
|
|
if isinstance(todo_text, str):
|
|
return todo_text.strip()
|
|
else:
|
|
return "Invalid TODO format."
|
|
except Exception as e:
|
|
return f"Error retrieving TODO: {e}"
|
|
|
|
def get_info_text(self):
|
|
try:
|
|
info_text = self.info_obj.todo.getinfo()
|
|
if isinstance(info_text, str):
|
|
return info_text.strip()
|
|
else:
|
|
return "Invalid"
|
|
except Exception as e:
|
|
return f"fuck you => {e}"
|
|
|
|
def get_archive_text(self):
|
|
try:
|
|
todo_archive_text = self.todo_archive_object.todo.getarchive()
|
|
if isinstance(todo_archive_text, str):
|
|
return todo_archive_text.strip()
|
|
else:
|
|
return "invalid format??"
|
|
except Exception as e:
|
|
return "?? ==> {e}"
|
|
|
|
def get_cam_text(self):
|
|
try:
|
|
cam_text = self.camobj.todo.getcams()
|
|
if isinstance(cam_text, str):
|
|
return cam_text.strip()
|
|
else:
|
|
return "invalid cam format"
|
|
except Exception as e:
|
|
return f"You are fuck you {e}" |