modern warfare 2025
All checks were successful
Build MuCaPy Executable / build-and-package (push) Successful in 1m42s
All checks were successful
Build MuCaPy Executable / build-and-package (push) Successful in 1m42s
This commit is contained in:
21
.vscode/launch.json
vendored
Normal file
21
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Python Debugger: Current File",
|
||||||
|
"type": "debugpy",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "externalTerminal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Python Debugger: Python File",
|
||||||
|
"type": "debugpy",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
139
mucapy/main.py
139
mucapy/main.py
@@ -17,6 +17,7 @@ from PyQt5.QtCore import Qt, QTimer, QDir, QSize, QSettings, QDateTime, QRect, Q
|
|||||||
from PyQt5.QtGui import (QImage, QPixmap, QIcon, QColor, QKeySequence, QPainter,
|
from PyQt5.QtGui import (QImage, QPixmap, QIcon, QColor, QKeySequence, QPainter,
|
||||||
QPen, QBrush)
|
QPen, QBrush)
|
||||||
import platform
|
import platform
|
||||||
|
import todo
|
||||||
import time
|
import time
|
||||||
import requests
|
import requests
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -68,8 +69,11 @@ class Config:
|
|||||||
try:
|
try:
|
||||||
# Ensure the file's directory exists
|
# Ensure the file's directory exists
|
||||||
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
|
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
|
||||||
with open(self.config_file, 'w') as f:
|
try:
|
||||||
json.dump(self.settings, f, indent=4)
|
with open(self.config_file, 'w') as f:
|
||||||
|
json.dump(self.settings, f, indent=4)
|
||||||
|
except FileNotFoundError:
|
||||||
|
exit(1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error saving config: {e}")
|
print(f"Error saving config: {e}")
|
||||||
|
|
||||||
@@ -421,8 +425,11 @@ class MultiCamYOLODetector(QObject):
|
|||||||
self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
|
self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
|
||||||
self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
|
self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
|
||||||
|
|
||||||
with open(classes_path, 'r') as f:
|
try:
|
||||||
self.classes = f.read().strip().split('\n')
|
with open(classes_path, 'r') as f:
|
||||||
|
self.classes = f.read().strip().split('\n')
|
||||||
|
except FileNotFoundError:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
np.random.seed(42)
|
np.random.seed(42)
|
||||||
self.colors = np.random.randint(0, 255, size=(len(self.classes), 3), dtype='uint8')
|
self.colors = np.random.randint(0, 255, size=(len(self.classes), 3), dtype='uint8')
|
||||||
@@ -566,8 +573,11 @@ class CameraDisplay(QLabel):
|
|||||||
self.setText("No camera feed")
|
self.setText("No camera feed")
|
||||||
|
|
||||||
self.get_camera_display_style = getpath.resource_path("styling/camera_display.qss")
|
self.get_camera_display_style = getpath.resource_path("styling/camera_display.qss")
|
||||||
with open(self.get_camera_display_style,"r") as cdst:
|
try:
|
||||||
self.setStyleSheet(cdst.read())
|
with open(self.get_camera_display_style,"r") as cdst:
|
||||||
|
self.setStyleSheet(cdst.read())
|
||||||
|
except FileNotFoundError:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
self.setMinimumSize(320, 240)
|
self.setMinimumSize(320, 240)
|
||||||
self.fullscreen_window = None
|
self.fullscreen_window = None
|
||||||
@@ -816,8 +826,11 @@ class AboutWindow(QDialog):
|
|||||||
self.toggle_btn.setCheckable(True)
|
self.toggle_btn.setCheckable(True)
|
||||||
self.toggle_btn.setChecked(False)
|
self.toggle_btn.setChecked(False)
|
||||||
toggle_btn_style = getpath.resource_path("styling/togglebtnabout.qss")
|
toggle_btn_style = getpath.resource_path("styling/togglebtnabout.qss")
|
||||||
with open(toggle_btn_style,"r") as tgbstyle:
|
try:
|
||||||
self.toggle_btn.setStyleSheet(tgbstyle.read())
|
with open(toggle_btn_style,"r") as tgbstyle:
|
||||||
|
self.toggle_btn.setStyleSheet(tgbstyle.read())
|
||||||
|
except FileNotFoundError:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
# Debug shit
|
# Debug shit
|
||||||
#print("i did shit")
|
#print("i did shit")
|
||||||
@@ -855,11 +868,44 @@ class AboutWindow(QDialog):
|
|||||||
|
|
||||||
# Set Styling for About Section
|
# Set Styling for About Section
|
||||||
style_file = getpath.resource_path("styling/about.qss")
|
style_file = getpath.resource_path("styling/about.qss")
|
||||||
with open(style_file,"r") as aboutstyle:
|
try:
|
||||||
self.setStyleSheet(aboutstyle.read())
|
with open(style_file,"r") as aboutstyle:
|
||||||
|
self.setStyleSheet(aboutstyle.read())
|
||||||
|
except FileNotFoundError:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
# Todo Label Shit
|
||||||
|
self.todo_obj = todo.todo()
|
||||||
|
todo_text = self.get_todo_text()
|
||||||
|
todo_label = QLabel(f"<pre>{todo_text}</pre>")
|
||||||
|
todo_label.setWordWrap(True)
|
||||||
|
todo_label.setAlignment(Qt.AlignCenter)
|
||||||
|
|
||||||
|
# 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}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
self.camobj = todo.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: #FFFF; font-style: italic;")
|
||||||
|
layout.addWidget(todo_label)
|
||||||
|
layout.addWidget(cam_label)
|
||||||
|
|
||||||
def toggle_expand(self, checked):
|
def toggle_expand(self, checked):
|
||||||
for key, label in self.full_labels.items():
|
for key, label in self.full_labels.items():
|
||||||
if key not in self.important_keys:
|
if key not in self.important_keys:
|
||||||
@@ -946,6 +992,26 @@ class AboutWindow(QDialog):
|
|||||||
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
def get_todo_text(self):
|
||||||
|
try:
|
||||||
|
todo_text = self.todo_obj.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_cam_text(self):
|
||||||
|
try:
|
||||||
|
cam_text = self.camobj.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}"
|
||||||
|
|
||||||
|
|
||||||
class NetworkCameraDialog(QDialog):
|
class NetworkCameraDialog(QDialog):
|
||||||
|
|
||||||
@@ -1438,8 +1504,11 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
# Set dark theme style
|
# Set dark theme style
|
||||||
style_file = getpath.resource_path("styling/mainwindow.qss")
|
style_file = getpath.resource_path("styling/mainwindow.qss")
|
||||||
with open(style_file, "r") as mainstyle:
|
try:
|
||||||
self.setStyleSheet(mainstyle.read())
|
with open(style_file, "r") as mainstyle:
|
||||||
|
self.setStyleSheet(mainstyle.read())
|
||||||
|
except FileNotFoundError:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
# Set palette for better dark mode support
|
# Set palette for better dark mode support
|
||||||
palette = self.palette()
|
palette = self.palette()
|
||||||
@@ -1958,9 +2027,12 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
# Set Styling from cpu progress QSS file
|
# Set Styling from cpu progress QSS file
|
||||||
style_file = getpath.resource_path("styling/cpu_progress.qss")
|
style_file = getpath.resource_path("styling/cpu_progress.qss")
|
||||||
with open(style_file,"r") as cpu_progress_style:
|
try:
|
||||||
self.cpu_progress.setStyleSheet(cpu_progress_style.read())
|
with open(style_file,"r") as cpu_progress_style:
|
||||||
|
self.cpu_progress.setStyleSheet(cpu_progress_style.read())
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
cpu_layout.addWidget(self.cpu_progress)
|
cpu_layout.addWidget(self.cpu_progress)
|
||||||
hw_monitor_layout.addLayout(cpu_layout)
|
hw_monitor_layout.addLayout(cpu_layout)
|
||||||
|
|
||||||
@@ -1976,9 +2048,12 @@ class MainWindow(QMainWindow):
|
|||||||
core_bar.setFormat("%p%")
|
core_bar.setFormat("%p%")
|
||||||
|
|
||||||
core_file = getpath.resource_path("styling/core_bar.qss")
|
core_file = getpath.resource_path("styling/core_bar.qss")
|
||||||
with open(core_file,"r") as core_bar_styling:
|
try:
|
||||||
core_bar.setStyleSheet(core_bar_styling.read())
|
with open(core_file,"r") as core_bar_styling:
|
||||||
|
core_bar.setStyleSheet(core_bar_styling.read())
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
cores_layout.addWidget(core_label, i, 0)
|
cores_layout.addWidget(core_label, i, 0)
|
||||||
cores_layout.addWidget(core_bar, i, 1)
|
cores_layout.addWidget(core_bar, i, 1)
|
||||||
self.core_bars.append(core_bar)
|
self.core_bars.append(core_bar)
|
||||||
@@ -2043,8 +2118,11 @@ class MainWindow(QMainWindow):
|
|||||||
for display in self.camera_displays:
|
for display in self.camera_displays:
|
||||||
display.setText("No camera feed")
|
display.setText("No camera feed")
|
||||||
cleardisplaypath = getpath.resource_path("styling/cleardisplay.qss")
|
cleardisplaypath = getpath.resource_path("styling/cleardisplay.qss")
|
||||||
with open(cleardisplaypath,"r") as cdstyle:
|
try:
|
||||||
display.setStyleSheet(cdstyle.read())
|
with open(cleardisplaypath,"r") as cdstyle:
|
||||||
|
display.setStyleSheet(cdstyle.read())
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
def update_feeds(self):
|
def update_feeds(self):
|
||||||
"""Update the camera feeds in the display"""
|
"""Update the camera feeds in the display"""
|
||||||
@@ -2271,6 +2349,13 @@ class MainWindow(QMainWindow):
|
|||||||
self.stop_btn.setEnabled(False)
|
self.stop_btn.setEnabled(False)
|
||||||
|
|
||||||
class initQT():
|
class initQT():
|
||||||
|
"""
|
||||||
|
This is a QOL Change if you prefer to do it the hard way. Or you just like to get Fist Fucked then i suggest you remove the Function Calls in the
|
||||||
|
Main Call of the Class!
|
||||||
|
|
||||||
|
This is not needed for Windows as it does this Automatically (at least i think)
|
||||||
|
If some shit that is supposed to happen isnt happening. Step through this Class Via Debuggers!
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.session_type = None # This is for QT #
|
self.session_type = None # This is for QT #
|
||||||
#--------------------#
|
#--------------------#
|
||||||
@@ -2280,11 +2365,6 @@ class initQT():
|
|||||||
# If the OS is Linux get Qts Session Type
|
# If the OS is Linux get Qts Session Type
|
||||||
if platform.system() == "Linux":
|
if platform.system() == "Linux":
|
||||||
self.session_type = os.getenv("XDG_SESSION_TYPE")
|
self.session_type = os.getenv("XDG_SESSION_TYPE")
|
||||||
|
|
||||||
# Enable this is stuff is exiting!
|
|
||||||
|
|
||||||
# print(f"got {self.session_type} ")
|
|
||||||
|
|
||||||
return self.session_type
|
return self.session_type
|
||||||
else:
|
else:
|
||||||
# If theres no Type then Exit 1
|
# If theres no Type then Exit 1
|
||||||
@@ -2299,10 +2379,6 @@ class initQT():
|
|||||||
# Set the Session Type to the one it got
|
# Set the Session Type to the one it got
|
||||||
if self.session_type:
|
if self.session_type:
|
||||||
os.environ["XDG_SESSION_TYPE"] = self.session_type
|
os.environ["XDG_SESSION_TYPE"] = self.session_type
|
||||||
|
|
||||||
# Enable if stuff is exiting!
|
|
||||||
|
|
||||||
# print(f"set the ENVVAR to {self.session_type}")
|
|
||||||
else:
|
else:
|
||||||
# If this fails then just exit with 1
|
# If this fails then just exit with 1
|
||||||
print(
|
print(
|
||||||
@@ -2319,14 +2395,14 @@ class initQT():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Initialize Qt if on Linux
|
# Initialize Qt if on Linux ; If shit fails then modify these Functions
|
||||||
if platform.system() == "Linux":
|
if platform.system() == "Linux":
|
||||||
qt = initQT()
|
qt = initQT()
|
||||||
qt.getenv()
|
qt.getenv()
|
||||||
qt.setenv()
|
qt.setenv()
|
||||||
qt.shutupCV()
|
qt.shutupCV()
|
||||||
else:
|
else:
|
||||||
# We do nothing, Windows doesnt need this
|
# We do nothing, Windows doesnt need this ; better shit anyways
|
||||||
pass
|
pass
|
||||||
|
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
@@ -2339,7 +2415,6 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# Set application style to Fusion for better dark mode support
|
# Set application style to Fusion for better dark mode support
|
||||||
app.setStyle("Fusion")
|
app.setStyle("Fusion")
|
||||||
|
|
||||||
|
|
||||||
window = MainWindow()
|
window = MainWindow()
|
||||||
window.show()
|
window.show()
|
||||||
|
|||||||
95
mucapy/styling/mw.qss
Normal file
95
mucapy/styling/mw.qss
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
QMainWindow, QWidget {
|
||||||
|
background-color: #2D2D2D;
|
||||||
|
color: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel {
|
||||||
|
color: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton {
|
||||||
|
background-color: #3A3A3A;
|
||||||
|
color: #DDD;
|
||||||
|
border: 1px solid #555;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:hover {
|
||||||
|
background-color: #4A4A4A;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:pressed {
|
||||||
|
background-color: #2A2A2A;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:disabled {
|
||||||
|
background-color: #2A2A2A;
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox, QSpinBox {
|
||||||
|
background-color: #3A3A3A;
|
||||||
|
color: #DDD;
|
||||||
|
border: 1px solid #555;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGroupBox {
|
||||||
|
border: 1px solid #555;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-top: 15px;
|
||||||
|
background-color: #252525;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGroupBox::title {
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
left: 10px;
|
||||||
|
padding: 0 3px;
|
||||||
|
color: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar {
|
||||||
|
background-color: #252525;
|
||||||
|
color: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item {
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item:selected {
|
||||||
|
background-color: #3A3A3A;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu {
|
||||||
|
background-color: #252525;
|
||||||
|
border: 1px solid #444;
|
||||||
|
color: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu::item:selected {
|
||||||
|
background-color: #3A3A3A;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollArea {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget {
|
||||||
|
titlebar-close-icon: url(none);
|
||||||
|
titlebar-normal-icon: url(none);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget::title {
|
||||||
|
background: #252525;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
5
mucapy/styling/todostyle.qss
Normal file
5
mucapy/styling/todostyle.qss
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
QLabel#todoLabel {
|
||||||
|
color:rgb(21, 255, 0);
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
50
mucapy/todo.py
Normal file
50
mucapy/todo.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
"""
|
||||||
|
Here we have a simple fucking class to get the fuckass Todo thing
|
||||||
|
Probably will do none of them
|
||||||
|
anyways, if you have suggestions pr this shit
|
||||||
|
|
||||||
|
idk if you are smarter than me then actually do them.
|
||||||
|
|
||||||
|
fuck you
|
||||||
|
-Rattatwinko 8.jun.25 (20:25)
|
||||||
|
"""
|
||||||
|
|
||||||
|
class todo:
|
||||||
|
def __init__(self):
|
||||||
|
#------------------------------------------------------------------------------------------------------------------------------------------------#
|
||||||
|
self.todo : str = """
|
||||||
|
|
||||||
|
Very Good Very Nice Todo List:
|
||||||
|
|
||||||
|
NOTE: If you want to run this in Visual Studio Codes built in Terminal you will get fucked in your tiny tight ass.
|
||||||
|
NOTE: If you are running this from the Build Executable from the Workflow , you ass is fine (you wont get fucked you slut)
|
||||||
|
NOTE: If you compiled this yourself ; you are one Fucking Genious
|
||||||
|
|
||||||
|
#-----------------------#
|
||||||
|
# Changes: #
|
||||||
|
# Not Very Much lolz #
|
||||||
|
#-----------------------#
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
[] - Fix Network Cameras from Crashing the Programm (This sometimes happens when only network cams are selected and it times out)
|
||||||
|
[] - Make Seperate Styling (unlikely that this will happen)
|
||||||
|
[] - RTSP Camera Streaming
|
||||||
|
[] - Make MJPEG more stable and efficient. (maybe use c++ for this or rust)
|
||||||
|
- NOTE: http://pendelcam.kip.uni-heidelberg.de/mjpg/video.mjpg
|
||||||
|
This is a Testing URL for MJPEG (stable and renders fine)
|
||||||
|
|
||||||
|
""" # This will display Centered (look in about window class)
|
||||||
|
#------------------------------------------------------------------------------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
self.cameraURL : str = """
|
||||||
|
Cameras:
|
||||||
|
- http://pendelcam.kip.uni-heidelberg.de/mjpg/video.mjpg
|
||||||
|
""" # This will also display centered
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
def gettodo(self) -> str:
|
||||||
|
return self.todo
|
||||||
|
def getcams(self) -> str:
|
||||||
|
return self.cameraURL
|
||||||
|
|
||||||
Reference in New Issue
Block a user