Merge dev to main, nearing completion #6

Merged
WorldTeacher merged 33 commits from dev into main 2025-05-13 15:32:46 +01:00
Showing only changes of commit b4c6169649 - Show all commits

View File

@@ -6,13 +6,13 @@ import sys
import tempfile
import webbrowser
from pathlib import Path
from typing import Any
from natsort import natsorted
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtCore import QThread
from PyQt6.QtGui import QRegularExpressionValidator
from src import Icon, logger, settings
from src import Icon, settings
from src.backend import Database, BookGrabber, AvailChecker, DocumentationThread
from src.backend.semester import Semester
from src.backend.create_file import recreateFile
@@ -24,7 +24,6 @@ from src.logic import (
ApparatData,
BookData,
csv_to_list,
word_docx_to_csv,
word_to_semap,
Prof,
Apparat,
@@ -52,6 +51,20 @@ from src.ui.widgets import (
EditProf,
)
from src.utils import SemesterDocument
from datetime import datetime
from loguru import logger as log
logger = log
logger.remove()
logger.add("logs/application.log", rotation="1 week", enqueue=True)
log.add(
f"logs/{datetime.now().strftime('%Y-%m-%d')}.log",
rotation="1 day",
compression="zip",
)
# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
logger.add(sys.stdout)
valid_input = (0, 0, 0, 0, 0, 0)
@@ -59,58 +72,58 @@ valid_input = (0, 0, 0, 0, 0, 0)
class Ui(Ui_Semesterapparat):
# use the Ui_MainWindow class from mainwindow.py
def __init__(self, MainWindow, username: str) -> None:
def __init__(self, MainWindow, username: str) -> None: # type:ignore
logger.info("Starting Semesterapparatsmanagement")
super().__init__()
self.active_user = username
self.setupUi(MainWindow)
self.MainWindow = MainWindow
self.setupUi(MainWindow) # type:ignore
self.MainWindow = MainWindow # type:ignore
# set the window title
MainWindow.setWindowTitle("Semesterapparatsmanagement")
MainWindow.setWindowIcon(Icon("logo").icon)
MainWindow.setWindowTitle("Semesterapparatsmanagement") # type:ignore
MainWindow.setWindowIcon(Icon("logo").icon) # type:ignore
self.db = Database()
self.btn_add_document.clicked.connect(self.add_document)
self.check_file.clicked.connect(
self.btn_add_document.clicked.connect(self.add_document) # type:ignore
self.check_file.clicked.connect( # type:ignore
self.btn_check_file_threaded
) # default: self.add_media_from_file
self.create_new_app.clicked.connect(self.btn_create_new_apparat)
self.btn_apparat_save.clicked.connect(lambda: self.btn_save_apparat(True))
self.btn_apparat_apply.clicked.connect(self.update_apparat)
self.btn_open_document.clicked.connect(self.open_document)
self.add_medium.clicked.connect(self.btn_add_medium)
self.btn_copy_adis_command.clicked.connect(self.text_to_clipboard)
self.btn_reserve.clicked.connect(self.check_availability)
self.create_document.clicked.connect(self.create_doc)
self.create_new_app.clicked.connect(self.btn_create_new_apparat) # type:ignore
self.btn_apparat_save.clicked.connect(lambda: self.btn_save_apparat(True)) # type:ignore
self.btn_apparat_apply.clicked.connect(self.update_apparat) # type:ignore
self.btn_open_document.clicked.connect(self.open_document) # type:ignore
self.add_medium.clicked.connect(self.btn_add_medium) # type:ignore
self.btn_copy_adis_command.clicked.connect(self.text_to_clipboard) # type:ignore
self.btn_reserve.clicked.connect(self.check_availability) # type:ignore
self.create_document.clicked.connect(self.create_doc) # type:ignore
self.calendarWidget = MessageCalendar(self.calendar_frame)
self.calendarWidget.setGridVisible(True)
self.calendarWidget.setVerticalHeaderFormat(
QtWidgets.QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader
)
self.calendarWidget.setObjectName("MessageCalendar")
self.calendarWidget.clicked.connect(self.open_reminder)
self.calendarWidget.clicked.connect(self.open_reminder) # type:ignore
# assign a context menu to the calendar
self.calendarlayout.addWidget(self.calendarWidget)
self.tableWidget_apparat_media.horizontalHeader().setSectionResizeMode(
self.tableWidget_apparat_media.horizontalHeader().setSectionResizeMode( # type:ignore
QtWidgets.QHeaderView.ResizeMode.Stretch
)
self.tableWidget_apparate.horizontalHeader().setSectionResizeMode(
self.tableWidget_apparate.horizontalHeader().setSectionResizeMode( # type:ignore
QtWidgets.QHeaderView.ResizeMode.Stretch
)
self.tableWidget_apparate.setSortingEnabled(True)
self.saveandcreate.hide()
# Actions
self.actionEinstellungen.triggered.connect(self.open_settings)
self.actionEinstellungen.triggered.connect(self.open_settings) # type:ignore
Icon("settings", self.actionEinstellungen)
self.actionDokumentation_lokal.triggered.connect(self.open_documentation)
self.actionDokumentation_lokal.triggered.connect(self.open_documentation) # type:ignore
Icon("offAction", self.actionBeenden)
self.actionBeenden.triggered.connect(self.quit)
self.actionAbout.triggered.connect(self.open_about)
self.actionBeenden.triggered.connect(self.quit) # type:ignore
self.actionAbout.triggered.connect(self.open_about) # type:ignore
# set validators
self.sem_sommer.clicked.connect(lambda: self.toggleButton(self.sem_winter))
self.sem_winter.clicked.connect(lambda: self.toggleButton(self.sem_sommer))
self.sem_sommer.clicked.connect(lambda: self.toggleButton(self.sem_winter)) # type:ignore
self.sem_winter.clicked.connect(lambda: self.toggleButton(self.sem_sommer)) # type:ignore
self.sem_year.setText(str(QtCore.QDate.currentDate().year()))
self.prof_mail.setValidator(
QRegularExpressionValidator(
@@ -139,7 +152,7 @@ class Ui(Ui_Semesterapparat):
self.tableWidget_apparate.addScrollBarWidget(
QtWidgets.QScrollBar(), QtCore.Qt.AlignmentFlag.AlignRight
)
self.tableWidget_apparate.doubleClicked.connect(self.load_app_data)
self.tableWidget_apparate.doubleClicked.connect(self.load_app_data) # type:ignore
# #print(f"user:{self.active_user}")
userrole = self.db.getRole(self.active_user)
@@ -152,18 +165,18 @@ class Ui(Ui_Semesterapparat):
self.populate_prof_dropdown()
self.populate_appfach_dropdown()
# if the focus is changed from the prof name dropdown, set the prof data if the prof exists in the database, otherwise show a message
self.drpdwn_prof_name.currentIndexChanged.connect(self.set_prof_data)
self.cancel_active_selection.clicked.connect(self.btn_cancel_active_selection)
self.check_eternal_app.stateChanged.connect(self.set_state)
self.drpdwn_prof_name.currentIndexChanged.connect(self.set_prof_data) # type:ignore
self.cancel_active_selection.clicked.connect(self.btn_cancel_active_selection) # type:ignore
self.check_eternal_app.stateChanged.connect(self.set_state) # type:ignore
# validate inputs
self.prof_mail.textChanged.connect(self.validate_prof_mail)
self.drpdwn_prof_name.editTextChanged.connect(self.validate_prof_name)
self.prof_tel_nr.textChanged.connect(self.validate_prof_tel)
self.app_name.textChanged.connect(self.validate_app_name)
self.app_fach.currentTextChanged.connect(self.validate_app_fach)
self.sem_year.textChanged.connect(self.validate_semester)
self.check_eternal_app.stateChanged.connect(self.validate_semester)
self.chkbx_show_del_media.stateChanged.connect(self.update_app_media_list)
self.prof_mail.textChanged.connect(self.validate_prof_mail) # type:ignore
self.drpdwn_prof_name.editTextChanged.connect(self.validate_prof_name) # type:ignore
self.prof_tel_nr.textChanged.connect(self.validate_prof_tel) # type:ignore
self.app_name.textChanged.connect(self.validate_app_name) # type:ignore
self.app_fach.currentTextChanged.connect(self.validate_app_fach) # type:ignore
self.sem_year.textChanged.connect(self.validate_semester) # type:ignore
self.check_eternal_app.stateChanged.connect(self.validate_semester) # type:ignore
self.chkbx_show_del_media.stateChanged.connect(self.update_app_media_list) # type:ignore
self.progress_label.setText("Bitte warten...")
# Set visibility/enabled state of certain entries
@@ -180,16 +193,16 @@ class Ui(Ui_Semesterapparat):
self.automation_add_selected_books.hide()
# self.btn_del_select_apparats.setEnabled(False)
self.tabWidget.currentChanged.connect(self.tabW1_changed)
self.tabWidget.currentChanged.connect(self.tabW1_changed) # type:ignore
# create a thread, that continually checks the validity of the inputs
self.validate_thread = QThread()
self.validate_thread.started.connect(self.thread_check)
self.validate_thread.started.connect(self.thread_check) # type:ignore
self.validate_thread.start()
self.add_medium.setEnabled(False)
self.docu = DocumentationThread()
self.docu.start()
self.actionDokumentation_lokal.triggered.connect(self.open_documentation)
self.actionDokumentation_lokal.triggered.connect(self.open_documentation) # type:ignore
# get all current apparats and cache them in a list
self.apparats = self.get_apparats()
@@ -205,15 +218,15 @@ class Ui(Ui_Semesterapparat):
self.tableWidget_apparat_media.setContextMenuPolicy(
QtCore.Qt.ContextMenuPolicy.CustomContextMenu
)
self.tableWidget_apparate.customContextMenuRequested.connect(
self.open_context_menu
self.tableWidget_apparate.customContextMenuRequested.connect( # type:ignore
self.open_context_menu # type:ignore
)
self.tableWidget_apparat_media.customContextMenuRequested.connect(
self.media_context_menu
self.tableWidget_apparat_media.customContextMenuRequested.connect( # type:ignore
self.media_context_menu # type:ignore
)
# admin buttons
self.select_action_box.currentTextChanged.connect(self.adminActions)
self.select_action_box.currentTextChanged.connect(self.adminActions) # type:ignore
self.select_action_box.addItem("")
self.select_action_box.setCurrentText("")
self.admin_action.setLayout(QtWidgets.QVBoxLayout())
@@ -1127,10 +1140,13 @@ class Ui(Ui_Semesterapparat):
).text()
logger.info("File selected: {}, {}", file_name, file_location)
if file_location == "Database":
logger.debug("Using file from database")
file = recreateFile(file_name, app_id, file_type, open=False)
logger.debug("recreated file from database")
else:
logger.debug("File not in database")
if not created:
logger.debug("File was not created, ")
self.add_files(prof_id)
if file_type == "pdf":
# Todo: implement parser here
@@ -1147,9 +1163,6 @@ class Ui(Ui_Semesterapparat):
logger.debug("Got the data: {}", data)
signatures = data.signatures
logger.info("Got the signatures: {}", signatures)
signatures = [i for i in signatures if i != ""]
# logger.debug(signatures)
# #print("starting thread")
if prof_id is None:
prof_id = self.db.getProfId(self.profdata)
@@ -1172,6 +1185,8 @@ class Ui(Ui_Semesterapparat):
autoGrabber.start()
while autoGrabber.isRunning():
QtWidgets.QApplication.processEvents()
# refresh book table
self.update_app_media_list()
# end of thread
# self.autoGrabber.exit()
# self.__clear_fields()
@@ -1277,7 +1292,15 @@ class Ui(Ui_Semesterapparat):
}
def add_files(self, prof_id=None):
files = []
"""
Add Files to the associated prof in the database
Parameters
----------
prof_id : int, optional
The ID associated to the prof, by default None
"""
files: list[dict[str, Any]] = []
for i in range(self.document_list.rowCount()):
files.append(
{