Merge changes from agent_branch to dev #5

Merged
WorldTeacher merged 15 commits from dev_fix_media_not_adding_agent into dev 2025-05-09 10:58:42 +01:00
Showing only changes of commit b4c6169649 - Show all commits

View File

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