From 424411b07721e31fa9cc89906b7f792ba84d669e Mon Sep 17 00:00:00 2001 From: WorldTeacher Date: Mon, 28 Apr 2025 15:31:35 +0200 Subject: [PATCH] add type checking, update deletion function in searchpage, add function to import apparat data from document --- src/__init__.py | 1 + src/backend/database.py | 40 +- src/ui/__init__.py | 2 +- src/ui/semesterapparat_ui.ui | 158 +++-- src/ui/semesterapparat_ui_ui.py | 1002 +++++++++++++++++++++++++++++++ src/ui/userInterface.py | 236 +++++--- src/ui/widgets/searchPage.py | 2 +- src/utils/blob.py | 2 +- src/utils/pickles.py | 5 +- 9 files changed, 1262 insertions(+), 186 deletions(-) create mode 100644 src/ui/semesterapparat_ui_ui.py diff --git a/src/__init__.py b/src/__init__.py index 88d2979..2661405 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,3 +1,4 @@ +__all__ = ["__version__", "__author__", "Icon", "settings"] from config import Config import os diff --git a/src/backend/database.py b/src/backend/database.py index 83f7a51..88d66c1 100644 --- a/src/backend/database.py +++ b/src/backend/database.py @@ -30,11 +30,9 @@ from loguru import logger as log logger = log logger.remove() -logger.add("logs/database.log", rotation="1 week", enqueue=True) +logger.add("logs/application.log", rotation="1 week", enqueue=True) log.add( - "logs/application.log", - rotation="1 day", - compression="zip", + "logs/database.log", ) # logger.add(sys.stderr, format="{time} {level} {message}", level="INFO") @@ -72,7 +70,7 @@ class Database: path = os.path.abspath(path) if not os.path.exists(path): # create path - # print(path) + # logger.debug(path) os.makedirs(path) if self.get_db_contents() == []: logger.critical("Database does not exist, creating tables") @@ -227,11 +225,11 @@ class Database: f"SELECT bookdata FROM media WHERE app_id={app_id} AND prof_id={prof_id}" ) logger.debug(t_query) - # # print(t_query) + # # logger.debug(t_query) result = cursor.execute(t_query).fetchall() result = [load_pickle(i[0]) for i in result] if bookdata in result: - # print("Bookdata already in database") + # logger.debug("Bookdata already in database") # check if the book was deleted in the apparat query = ( "SELECT deleted FROM media WHERE app_id=? AND prof_id=? AND bookdata=?" @@ -239,7 +237,7 @@ class Database: params = (app_id, prof_id, dump_pickle(bookdata)) result = cursor.execute(query, params).fetchone() if result[0] == 1: - # print("Book was deleted, updating bookdata") + # logger.debug("Book was deleted, updating bookdata") query = "UPDATE media SET deleted=0 WHERE app_id=? AND prof_id=? AND bookdata=?" params = (app_id, prof_id, dump_pickle(bookdata)) cursor.execute(query, params) @@ -511,7 +509,7 @@ class Database: delete=False, dir=tempdir_path, mode="wb", suffix=f".{filetype}" ) file.write(blob) - # print("file created") + # logger.debug("file created") return file.name def getFiles(self, app_id: Union[str, int], prof_id: int) -> list[tuple]: @@ -539,7 +537,7 @@ class Database: return [i[0] for i in data] def insertSubjects(self): - # print("Inserting subjects") + # logger.debug("Inserting subjects") subjects = [ "Biologie", "Chemie", @@ -897,7 +895,7 @@ class Database: ) ret = [] for i in data: - print(i) + logger.debug(i) ret.append(Apparat().from_tuple(i)) return ret @@ -1110,9 +1108,9 @@ class Database: kwargs["dauer"] = kwargs["dauer"].replace("Ja", "1").replace("Nein", "0") query = "SELECT * FROM semesterapparat WHERE " for key, value in kwargs.items() if kwargs.items() is not None else {}: - # print(key, value) + # logger.debug(key, value) query += f"{key}='{value}' AND " - # print(query) + # logger.debug(query) # remove deletesemester part from normal query, as this will be added to the database upon deleting the apparat if "deletesemester" in kwargs.keys(): query = query.replace( @@ -1128,7 +1126,7 @@ class Database: query = query.replace( f"endsemester='{kwargs['endsemester']}' AND ", "xyz" ) - # print("replaced") + # logger.debug("replaced") query = query.replace( "xyz", f"(erstellsemester='{kwargs['endsemester']}' OR verlängerung_bis='{kwargs['endsemester']}') AND ", @@ -1143,9 +1141,9 @@ class Database: query = query[:-1] query = query.strip() - # print(query) + # logger.debug(query) res = __query(query) - # print(res) + # logger.debug(res) return res # Admin data @@ -1314,15 +1312,15 @@ class Database: """ return self.query_db("SELECT titel, fname,lname,mail,telnr,fullname FROM prof") - def restoreApparat(self, app_id: Union[str, int]): + def restoreApparat(self, app_id: Union[str, int], app_name: str): """restore an apparat from the database Args: app_id (Union[str, int]): the id of the apparat """ return self.query_db( - "UPDATE semesterapparat SET deletion_status=0, deleted_date=NULL WHERE appnr=?", - (app_id,), + "UPDATE semesterapparat SET deletion_status=0, deleted_date=NULL WHERE appnr=? and name=?", + (app_id, app_name), ) # ELSA @@ -1433,7 +1431,7 @@ class Database: blob = self.query_db( "SELECT fileblob FROM elsa_files WHERE filename=?", (filename,), one=True )[0] - # print(blob) + # logger.debug(blob) tempdir = self.database.tempdir tempdir = tempdir.replace("~", str(Path.home())) tempdir_path = Path(tempdir) @@ -1443,7 +1441,7 @@ class Database: delete=False, dir=tempdir_path, mode="wb", suffix=f".{filetype}" ) file.write(blob) - # print("file created") + # logger.debug("file created") return file.name def getElsaApparats(self) -> ELSA: diff --git a/src/ui/__init__.py b/src/ui/__init__.py index 620967d..0867516 100644 --- a/src/ui/__init__.py +++ b/src/ui/__init__.py @@ -1,6 +1,6 @@ import pathlib -from .Ui_semesterapparat_ui import Ui_MainWindow as Ui_Semesterapparat +from .semesterapparat_ui_ui import Ui_MainWindow as Ui_Semesterapparat # from .dialogs import ( # ApparatExtendDialog, diff --git a/src/ui/semesterapparat_ui.ui b/src/ui/semesterapparat_ui.ui index 734317d..c458296 100644 --- a/src/ui/semesterapparat_ui.ui +++ b/src/ui/semesterapparat_ui.ui @@ -595,67 +595,6 @@ - - - - 1110 - 120 - 131 - 51 - - - - - 9 - false - - - - Abhängig von der Anzahl der Medien kann die Suche sehr lange dauern - - - Medien aus Dokument - hinzufügen - - - - - - 1110 - 80 - 131 - 25 - - - - - 9 - false - - - - Dokument öffnen - - - - - - 1110 - 40 - 131 - 25 - - - - - 9 - false - - - - Dokument hinzufügen - - @@ -1506,6 +1445,103 @@ Speichern und anlegen + + + + 1110 + 17 + 131 + 181 + + + + + + + + 0 + 0 + + + + + 9 + false + + + + Dokument hinzufügen + + + + + + + + 0 + 0 + + + + + 9 + false + + + + Dokument öffnen + + + + + + + + 0 + 0 + + + + + 9 + false + + + + Abhängig von der Anzahl der Medien kann die Suche sehr lange dauern + + + Medien aus Dokument + hinzufügen + + + + + + + + 0 + 0 + + + + + 9 + false + + + + Die Apparatsdetails werden aus dem Dokument gelesen und eingetragen +Einige Angaben müssen ggf angepasst werden + + + Daten aus Dokument +übernehmen + + + + + diff --git a/src/ui/semesterapparat_ui_ui.py b/src/ui/semesterapparat_ui_ui.py new file mode 100644 index 0000000..b4a1be2 --- /dev/null +++ b/src/ui/semesterapparat_ui_ui.py @@ -0,0 +1,1002 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\semesterapparat_ui.ui' +# +# Created by: PyQt6 UI code generator 6.8.0 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.setWindowModality(QtCore.Qt.WindowModality.WindowModal) + MainWindow.setEnabled(True) + MainWindow.resize(1590, 800) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + MainWindow.setMinimumSize(QtCore.QSize(1278, 800)) + MainWindow.setMaximumSize(QtCore.QSize(1590, 800)) + MainWindow.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap("c:\\Users\\aky547\\GitHub\\SemesterapparatsManager\\src\\ui\\../../../../../../icons/logo.ico"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + MainWindow.setWindowIcon(icon) + MainWindow.setStatusTip("") + self.centralwidget = QtWidgets.QWidget(parent=MainWindow) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) + self.centralwidget.setSizePolicy(sizePolicy) + self.centralwidget.setObjectName("centralwidget") + self.verticalLayoutWidget = QtWidgets.QWidget(parent=self.centralwidget) + self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 1271, 751)) + self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") + self.mainLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) + self.mainLayout.setContentsMargins(0, 0, 0, 0) + self.mainLayout.setObjectName("mainLayout") + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + self.tabWidget = QtWidgets.QTabWidget(parent=self.verticalLayoutWidget) + self.tabWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tabWidget.setObjectName("tabWidget") + self.createApparat = QtWidgets.QWidget() + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.createApparat.sizePolicy().hasHeightForWidth()) + self.createApparat.setSizePolicy(sizePolicy) + self.createApparat.setObjectName("createApparat") + self.horizontalLayoutWidget_2 = QtWidgets.QWidget(parent=self.createApparat) + self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1261, 163)) + self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2) + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.formLayout = QtWidgets.QFormLayout() + self.formLayout.setObjectName("formLayout") + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem) + self.create_document = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_2) + self.create_document.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.create_document.setObjectName("create_document") + self.verticalLayout_2.addWidget(self.create_document) + self.create_new_app = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_2) + self.create_new_app.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.create_new_app.setObjectName("create_new_app") + self.verticalLayout_2.addWidget(self.create_new_app) + self.cancel_active_selection = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_2) + self.cancel_active_selection.setEnabled(False) + self.cancel_active_selection.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.cancel_active_selection.setObjectName("cancel_active_selection") + self.verticalLayout_2.addWidget(self.cancel_active_selection) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem1) + self.formLayout.setLayout(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.verticalLayout_2) + self.tableWidget_apparate = QtWidgets.QTableWidget(parent=self.horizontalLayoutWidget_2) + self.tableWidget_apparate.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tableWidget_apparate.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.tableWidget_apparate.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidget_apparate.setAlternatingRowColors(True) + self.tableWidget_apparate.setTextElideMode(QtCore.Qt.TextElideMode.ElideMiddle) + self.tableWidget_apparate.setObjectName("tableWidget_apparate") + self.tableWidget_apparate.setColumnCount(6) + self.tableWidget_apparate.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(5, item) + self.tableWidget_apparate.horizontalHeader().setCascadingSectionResizes(True) + self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.tableWidget_apparate) + self.horizontalLayout_2.addLayout(self.formLayout) + self.line = QtWidgets.QFrame(parent=self.createApparat) + self.line.setGeometry(QtCore.QRect(0, 160, 1261, 21)) + self.line.setFrameShape(QtWidgets.QFrame.Shape.HLine) + self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line.setObjectName("line") + self.gridLayoutWidget_2 = QtWidgets.QWidget(parent=self.createApparat) + self.gridLayoutWidget_2.setEnabled(True) + self.gridLayoutWidget_2.setGeometry(QtCore.QRect(0, 180, 1261, 511)) + self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2") + self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2) + self.gridLayout_2.setContentsMargins(0, 0, 0, 0) + self.gridLayout_2.setObjectName("gridLayout_2") + self.horizontalLayout_5 = QtWidgets.QHBoxLayout() + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + spacerItem2 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem2) + self.chkbx_show_del_media = QtWidgets.QCheckBox(parent=self.gridLayoutWidget_2) + self.chkbx_show_del_media.setObjectName("chkbx_show_del_media") + self.horizontalLayout_5.addWidget(self.chkbx_show_del_media) + spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem3) + self.btn_reserve = QtWidgets.QPushButton(parent=self.gridLayoutWidget_2) + self.btn_reserve.setObjectName("btn_reserve") + self.horizontalLayout_5.addWidget(self.btn_reserve) + self.add_layout = QtWidgets.QHBoxLayout() + self.add_layout.setObjectName("add_layout") + self.label_info = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.label_info.setObjectName("label_info") + self.add_layout.addWidget(self.label_info) + self.line_2 = QtWidgets.QFrame(parent=self.gridLayoutWidget_2) + self.line_2.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line_2.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line_2.setObjectName("line_2") + self.add_layout.addWidget(self.line_2) + self.progress_label = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.progress_label.setObjectName("progress_label") + self.add_layout.addWidget(self.progress_label) + self.horizontalLayout_5.addLayout(self.add_layout) + spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem4) + self.avail_layout = QtWidgets.QHBoxLayout() + self.avail_layout.setObjectName("avail_layout") + self.horizontalLayout_5.addLayout(self.avail_layout) + self.label_20 = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.label_20.setObjectName("label_20") + self.horizontalLayout_5.addWidget(self.label_20) + self.line_3 = QtWidgets.QFrame(parent=self.gridLayoutWidget_2) + self.line_3.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line_3.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line_3.setObjectName("line_3") + self.horizontalLayout_5.addWidget(self.line_3) + self.avail_status = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.avail_status.setObjectName("avail_status") + self.horizontalLayout_5.addWidget(self.avail_status) + self.automation_add_selected_books = QtWidgets.QPushButton(parent=self.gridLayoutWidget_2) + self.automation_add_selected_books.setObjectName("automation_add_selected_books") + self.horizontalLayout_5.addWidget(self.automation_add_selected_books) + spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem5) + self.gridLayout_2.addLayout(self.horizontalLayout_5, 4, 0, 1, 1) + self.tableWidget_apparat_media = QtWidgets.QTableWidget(parent=self.gridLayoutWidget_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tableWidget_apparat_media.sizePolicy().hasHeightForWidth()) + self.tableWidget_apparat_media.setSizePolicy(sizePolicy) + self.tableWidget_apparat_media.setMinimumSize(QtCore.QSize(1259, 0)) + self.tableWidget_apparat_media.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tableWidget_apparat_media.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu) + self.tableWidget_apparat_media.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.tableWidget_apparat_media.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidget_apparat_media.setAlternatingRowColors(True) + self.tableWidget_apparat_media.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.tableWidget_apparat_media.setObjectName("tableWidget_apparat_media") + self.tableWidget_apparat_media.setColumnCount(7) + self.tableWidget_apparat_media.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(5, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(6, item) + self.tableWidget_apparat_media.horizontalHeader().setCascadingSectionResizes(True) + self.gridLayout_2.addWidget(self.tableWidget_apparat_media, 9, 0, 1, 1) + self.label = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(11) + font.setBold(True) + self.label.setFont(font) + self.label.setObjectName("label") + self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1) + self.app_group_box = QtWidgets.QGroupBox(parent=self.gridLayoutWidget_2) + self.app_group_box.setEnabled(True) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.app_group_box.sizePolicy().hasHeightForWidth()) + self.app_group_box.setSizePolicy(sizePolicy) + self.app_group_box.setMinimumSize(QtCore.QSize(0, 210)) + font = QtGui.QFont() + font.setPointSize(12) + font.setBold(True) + self.app_group_box.setFont(font) + self.app_group_box.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.app_group_box.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) + self.app_group_box.setCheckable(False) + self.app_group_box.setObjectName("app_group_box") + self.document_list = QtWidgets.QTableWidget(parent=self.app_group_box) + self.document_list.setGeometry(QtCore.QRect(780, 20, 321, 181)) + font = QtGui.QFont() + font.setPointSize(10) + font.setBold(False) + font.setKerning(False) + self.document_list.setFont(font) + self.document_list.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.document_list.setAcceptDrops(True) + self.document_list.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff) + self.document_list.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.document_list.setDragEnabled(True) + self.document_list.setDragDropMode(QtWidgets.QAbstractItemView.DragDropMode.DragOnly) + self.document_list.setDefaultDropAction(QtCore.Qt.DropAction.LinkAction) + self.document_list.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.document_list.setObjectName("document_list") + self.document_list.setColumnCount(4) + self.document_list.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.document_list.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.document_list.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.document_list.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.document_list.setHorizontalHeaderItem(3, item) + self.document_list.horizontalHeader().setDefaultSectionSize(107) + self.appname_mand = QtWidgets.QLabel(parent=self.app_group_box) + self.appname_mand.setGeometry(QtCore.QRect(330, 50, 16, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.appname_mand.setFont(font) + self.appname_mand.setObjectName("appname_mand") + self.profname_mand = QtWidgets.QLabel(parent=self.app_group_box) + self.profname_mand.setGeometry(QtCore.QRect(110, 110, 16, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.profname_mand.setFont(font) + self.profname_mand.setObjectName("profname_mand") + self.prof_title = QtWidgets.QLineEdit(parent=self.app_group_box) + self.prof_title.setGeometry(QtCore.QRect(120, 80, 71, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.prof_title.setFont(font) + self.prof_title.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus) + self.prof_title.setObjectName("prof_title") + self.fach_mand = QtWidgets.QLabel(parent=self.app_group_box) + self.fach_mand.setGeometry(QtCore.QRect(510, 50, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.fach_mand.setFont(font) + self.fach_mand.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.fach_mand.setObjectName("fach_mand") + self.btn_apparat_apply = QtWidgets.QPushButton(parent=self.app_group_box) + self.btn_apparat_apply.setGeometry(QtCore.QRect(360, 150, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.btn_apparat_apply.setFont(font) + self.btn_apparat_apply.setObjectName("btn_apparat_apply") + self.label_9 = QtWidgets.QLabel(parent=self.app_group_box) + self.label_9.setGeometry(QtCore.QRect(20, 160, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_9.setFont(font) + self.label_9.setObjectName("label_9") + self.gridLayoutWidget_5 = QtWidgets.QWidget(parent=self.app_group_box) + self.gridLayoutWidget_5.setGeometry(QtCore.QRect(520, 30, 241, 61)) + self.gridLayoutWidget_5.setObjectName("gridLayoutWidget_5") + self.gridLayout_6 = QtWidgets.QGridLayout(self.gridLayoutWidget_5) + self.gridLayout_6.setContentsMargins(0, 0, 0, 0) + self.gridLayout_6.setObjectName("gridLayout_6") + self.app_fach = QtWidgets.QComboBox(parent=self.gridLayoutWidget_5) + self.app_fach.setMaximumSize(QtCore.QSize(16777215, 25)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.app_fach.setFont(font) + self.app_fach.setEditable(True) + self.app_fach.setObjectName("app_fach") + self.gridLayout_6.addWidget(self.app_fach, 0, 1, 1, 1) + spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout_6.addItem(spacerItem6, 0, 3, 1, 1) + self.valid_check_app_fach = QtWidgets.QToolButton(parent=self.gridLayoutWidget_5) + self.valid_check_app_fach.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.valid_check_app_fach.setText("") + self.valid_check_app_fach.setAutoRaise(True) + self.valid_check_app_fach.setArrowType(QtCore.Qt.ArrowType.NoArrow) + self.valid_check_app_fach.setObjectName("valid_check_app_fach") + self.gridLayout_6.addWidget(self.valid_check_app_fach, 0, 2, 1, 1) + self._mand = QtWidgets.QLabel(parent=self.app_group_box) + self._mand.setGeometry(QtCore.QRect(330, 90, 16, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self._mand.setFont(font) + self._mand.setObjectName("_mand") + self.prof_tel_nr = QtWidgets.QLineEdit(parent=self.app_group_box) + self.prof_tel_nr.setGeometry(QtCore.QRect(120, 160, 121, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.prof_tel_nr.setFont(font) + self.prof_tel_nr.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhNone) + self.prof_tel_nr.setPlaceholderText("") + self.prof_tel_nr.setObjectName("prof_tel_nr") + self.check_eternal_app = QtWidgets.QCheckBox(parent=self.app_group_box) + self.check_eternal_app.setEnabled(False) + self.check_eternal_app.setGeometry(QtCore.QRect(340, 120, 101, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.check_eternal_app.setFont(font) + self.check_eternal_app.setObjectName("check_eternal_app") + self.sem_sommer = QtWidgets.QCheckBox(parent=self.app_group_box) + self.sem_sommer.setGeometry(QtCore.QRect(340, 100, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.sem_sommer.setFont(font) + self.sem_sommer.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.sem_sommer.setObjectName("sem_sommer") + self.drpdwn_prof_name = QtWidgets.QComboBox(parent=self.app_group_box) + self.drpdwn_prof_name.setGeometry(QtCore.QRect(120, 110, 121, 22)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.drpdwn_prof_name.setFont(font) + self.drpdwn_prof_name.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.drpdwn_prof_name.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhNone) + self.drpdwn_prof_name.setEditable(True) + self.drpdwn_prof_name.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically) + self.drpdwn_prof_name.setPlaceholderText("") + self.drpdwn_prof_name.setFrame(True) + self.drpdwn_prof_name.setObjectName("drpdwn_prof_name") + self.mail_mand = QtWidgets.QLabel(parent=self.app_group_box) + self.mail_mand.setGeometry(QtCore.QRect(110, 140, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.mail_mand.setFont(font) + self.mail_mand.setObjectName("mail_mand") + self.label_3 = QtWidgets.QLabel(parent=self.app_group_box) + self.label_3.setGeometry(QtCore.QRect(20, 80, 61, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_3.setFont(font) + self.label_3.setObjectName("label_3") + self.label_2 = QtWidgets.QLabel(parent=self.app_group_box) + self.label_2.setGeometry(QtCore.QRect(20, 50, 101, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_2.setFont(font) + self.label_2.setObjectName("label_2") + self.label_8 = QtWidgets.QLabel(parent=self.app_group_box) + self.label_8.setGeometry(QtCore.QRect(20, 140, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_8.setFont(font) + self.label_8.setObjectName("label_8") + self.label_10 = QtWidgets.QLabel(parent=self.app_group_box) + self.label_10.setGeometry(QtCore.QRect(480, 50, 51, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_10.setFont(font) + self.label_10.setObjectName("label_10") + self.prof_mail = QtWidgets.QLineEdit(parent=self.app_group_box) + self.prof_mail.setGeometry(QtCore.QRect(120, 140, 121, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.prof_mail.setFont(font) + self.prof_mail.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhEmailCharactersOnly) + self.prof_mail.setMaxLength(200) + self.prof_mail.setPlaceholderText("") + self.prof_mail.setObjectName("prof_mail") + self.formLayoutWidget_2 = QtWidgets.QWidget(parent=self.app_group_box) + self.formLayoutWidget_2.setGeometry(QtCore.QRect(560, 100, 211, 99)) + self.formLayoutWidget_2.setObjectName("formLayoutWidget_2") + self.formLayout_3 = QtWidgets.QFormLayout(self.formLayoutWidget_2) + self.formLayout_3.setContentsMargins(0, 0, 0, 0) + self.formLayout_3.setObjectName("formLayout_3") + self.label_12 = QtWidgets.QLabel(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_12.setFont(font) + self.label_12.setObjectName("label_12") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_12) + self.prof_id_adis = QtWidgets.QLineEdit(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.prof_id_adis.setFont(font) + self.prof_id_adis.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhPreferNumbers) + self.prof_id_adis.setText("") + self.prof_id_adis.setObjectName("prof_id_adis") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.prof_id_adis) + self.label_13 = QtWidgets.QLabel(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_13.setFont(font) + self.label_13.setObjectName("label_13") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_13) + self.apparat_id_adis = QtWidgets.QLineEdit(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.apparat_id_adis.setFont(font) + self.apparat_id_adis.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhPreferNumbers) + self.apparat_id_adis.setObjectName("apparat_id_adis") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.apparat_id_adis) + self.sem_year = QtWidgets.QLineEdit(parent=self.app_group_box) + self.sem_year.setGeometry(QtCore.QRect(410, 90, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.sem_year.setFont(font) + self.sem_year.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.sem_year.setMaxLength(5) + self.sem_year.setObjectName("sem_year") + self.check_send_mail = QtWidgets.QCheckBox(parent=self.app_group_box) + self.check_send_mail.setGeometry(QtCore.QRect(450, 150, 91, 24)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.check_send_mail.setFont(font) + self.check_send_mail.setObjectName("check_send_mail") + self.sem_winter = QtWidgets.QCheckBox(parent=self.app_group_box) + self.sem_winter.setGeometry(QtCore.QRect(340, 80, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.sem_winter.setFont(font) + self.sem_winter.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.sem_winter.setObjectName("sem_winter") + self.label_4 = QtWidgets.QLabel(parent=self.app_group_box) + self.label_4.setGeometry(QtCore.QRect(20, 110, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_4.setFont(font) + self.label_4.setObjectName("label_4") + self.telnr_mand = QtWidgets.QLabel(parent=self.app_group_box) + self.telnr_mand.setGeometry(QtCore.QRect(110, 160, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.telnr_mand.setFont(font) + self.telnr_mand.setObjectName("telnr_mand") + self.btn_apparat_save = QtWidgets.QPushButton(parent=self.app_group_box) + self.btn_apparat_save.setGeometry(QtCore.QRect(270, 150, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.btn_apparat_save.setFont(font) + self.btn_apparat_save.setStatusTip("") + self.btn_apparat_save.setObjectName("btn_apparat_save") + self.label_5 = QtWidgets.QLabel(parent=self.app_group_box) + self.label_5.setGeometry(QtCore.QRect(250, 50, 91, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_5.setFont(font) + self.label_5.setObjectName("label_5") + self.app_name = QtWidgets.QLineEdit(parent=self.app_group_box) + self.app_name.setGeometry(QtCore.QRect(340, 50, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.app_name.setFont(font) + self.app_name.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.app_name.setObjectName("app_name") + self.drpdwn_app_nr = QtWidgets.QComboBox(parent=self.app_group_box) + self.drpdwn_app_nr.setGeometry(QtCore.QRect(120, 50, 69, 22)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.drpdwn_app_nr.setFont(font) + self.drpdwn_app_nr.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhNone) + self.drpdwn_app_nr.setEditable(True) + self.drpdwn_app_nr.setObjectName("drpdwn_app_nr") + self.label_6 = QtWidgets.QLabel(parent=self.app_group_box) + self.label_6.setGeometry(QtCore.QRect(270, 90, 61, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.label_6.setFont(font) + self.label_6.setObjectName("label_6") + self.valid_check_profname = QtWidgets.QToolButton(parent=self.app_group_box) + self.valid_check_profname.setGeometry(QtCore.QRect(240, 110, 23, 22)) + self.valid_check_profname.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.valid_check_profname.setText("") + self.valid_check_profname.setAutoRaise(True) + self.valid_check_profname.setArrowType(QtCore.Qt.ArrowType.NoArrow) + self.valid_check_profname.setObjectName("valid_check_profname") + self.valid_check_appname = QtWidgets.QToolButton(parent=self.app_group_box) + self.valid_check_appname.setGeometry(QtCore.QRect(450, 50, 22, 22)) + self.valid_check_appname.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.valid_check_appname.setText("") + self.valid_check_appname.setAutoRaise(True) + self.valid_check_appname.setObjectName("valid_check_appname") + self.valid_check_semester = QtWidgets.QToolButton(parent=self.app_group_box) + self.valid_check_semester.setGeometry(QtCore.QRect(520, 90, 22, 22)) + self.valid_check_semester.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.valid_check_semester.setText("") + self.valid_check_semester.setAutoRaise(True) + self.valid_check_semester.setObjectName("valid_check_semester") + self.valid_check_mail = QtWidgets.QToolButton(parent=self.app_group_box) + self.valid_check_mail.setGeometry(QtCore.QRect(240, 140, 22, 22)) + self.valid_check_mail.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.valid_check_mail.setText("") + self.valid_check_mail.setAutoRaise(True) + self.valid_check_mail.setObjectName("valid_check_mail") + self.valid_check_telnr = QtWidgets.QToolButton(parent=self.app_group_box) + self.valid_check_telnr.setGeometry(QtCore.QRect(240, 160, 22, 22)) + self.valid_check_telnr.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.valid_check_telnr.setText("") + self.valid_check_telnr.setAutoRaise(True) + self.valid_check_telnr.setObjectName("valid_check_telnr") + self.saveandcreate = QtWidgets.QPushButton(parent=self.app_group_box) + self.saveandcreate.setEnabled(False) + self.saveandcreate.setGeometry(QtCore.QRect(270, 180, 161, 24)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.saveandcreate.setFont(font) + self.saveandcreate.setObjectName("saveandcreate") + self.verticalLayoutWidget_3 = QtWidgets.QWidget(parent=self.app_group_box) + self.verticalLayoutWidget_3.setGeometry(QtCore.QRect(1110, 17, 131, 181)) + self.verticalLayoutWidget_3.setObjectName("verticalLayoutWidget_3") + self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_3) + self.verticalLayout_8.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_8.setObjectName("verticalLayout_8") + self.btn_add_document = QtWidgets.QPushButton(parent=self.verticalLayoutWidget_3) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.btn_add_document.sizePolicy().hasHeightForWidth()) + self.btn_add_document.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.btn_add_document.setFont(font) + self.btn_add_document.setObjectName("btn_add_document") + self.verticalLayout_8.addWidget(self.btn_add_document) + self.btn_open_document = QtWidgets.QPushButton(parent=self.verticalLayoutWidget_3) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.btn_open_document.sizePolicy().hasHeightForWidth()) + self.btn_open_document.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.btn_open_document.setFont(font) + self.btn_open_document.setObjectName("btn_open_document") + self.verticalLayout_8.addWidget(self.btn_open_document) + self.check_file = QtWidgets.QPushButton(parent=self.verticalLayoutWidget_3) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.check_file.sizePolicy().hasHeightForWidth()) + self.check_file.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.check_file.setFont(font) + self.check_file.setObjectName("check_file") + self.verticalLayout_8.addWidget(self.check_file) + self.btn_extract_data_from_document = QtWidgets.QPushButton(parent=self.verticalLayoutWidget_3) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.btn_extract_data_from_document.sizePolicy().hasHeightForWidth()) + self.btn_extract_data_from_document.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + self.btn_extract_data_from_document.setFont(font) + self.btn_extract_data_from_document.setObjectName("btn_extract_data_from_document") + self.verticalLayout_8.addWidget(self.btn_extract_data_from_document) + self.verticalLayout_8.setStretch(0, 1) + self.verticalLayout_8.setStretch(1, 1) + self.verticalLayout_8.setStretch(2, 2) + self.verticalLayout_8.setStretch(3, 2) + self.gridLayout_2.addWidget(self.app_group_box, 1, 0, 1, 1) + self.add_medium = QtWidgets.QPushButton(parent=self.createApparat) + self.add_medium.setGeometry(QtCore.QRect(3, 695, 121, 20)) + self.add_medium.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.add_medium.setObjectName("add_medium") + self.tabWidget.addTab(self.createApparat, "") + self.search_statistics = QtWidgets.QWidget() + self.search_statistics.setObjectName("search_statistics") + self.tabWidget.addTab(self.search_statistics, "") + self.elsatab = QtWidgets.QWidget() + self.elsatab.setObjectName("elsatab") + self.tabWidget.addTab(self.elsatab, "") + self.admin = QtWidgets.QWidget() + self.admin.setObjectName("admin") + self.label_21 = QtWidgets.QLabel(parent=self.admin) + self.label_21.setGeometry(QtCore.QRect(10, 30, 47, 22)) + self.label_21.setObjectName("label_21") + self.select_action_box = QtWidgets.QComboBox(parent=self.admin) + self.select_action_box.setGeometry(QtCore.QRect(60, 30, 181, 22)) + self.select_action_box.setObjectName("select_action_box") + self.select_action_box.addItem("") + self.select_action_box.addItem("") + self.select_action_box.addItem("") + self.admin_action = QtWidgets.QGroupBox(parent=self.admin) + self.admin_action.setGeometry(QtCore.QRect(10, 70, 570, 291)) + font = QtGui.QFont() + font.setBold(False) + self.admin_action.setFont(font) + self.admin_action.setFlat(True) + self.admin_action.setCheckable(False) + self.admin_action.setObjectName("admin_action") + self.tabWidget.addTab(self.admin, "") + self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) + self.horizontalLayout.addLayout(self.gridLayout) + self.mainLayout.addLayout(self.horizontalLayout) + self.verticalLayoutWidget_2 = QtWidgets.QWidget(parent=self.centralwidget) + self.verticalLayoutWidget_2.setGeometry(QtCore.QRect(1280, 0, 306, 751)) + self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2") + self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setObjectName("verticalLayout") + self.calendar_frame = QtWidgets.QFrame(parent=self.verticalLayoutWidget_2) + self.calendar_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.calendar_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.calendar_frame.setObjectName("calendar_frame") + self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.calendar_frame) + self.verticalLayout_7.setObjectName("verticalLayout_7") + self.calendarlayout = QtWidgets.QVBoxLayout() + self.calendarlayout.setObjectName("calendarlayout") + self.verticalLayout_7.addLayout(self.calendarlayout) + self.verticalLayout.addWidget(self.calendar_frame) + self.frame_creation_progress = QtWidgets.QFrame(parent=self.verticalLayoutWidget_2) + self.frame_creation_progress.setObjectName("frame_creation_progress") + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_creation_progress) + self.verticalLayout_4.setSpacing(6) + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.steps = QtWidgets.QFrame(parent=self.frame_creation_progress) + self.steps.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.steps.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.steps.setObjectName("steps") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.steps) + self.verticalLayout_3.setSpacing(0) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.groupBox_2 = QtWidgets.QGroupBox(parent=self.steps) + self.groupBox_2.setEnabled(True) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.groupBox_2.sizePolicy().hasHeightForWidth()) + self.groupBox_2.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(11) + font.setBold(True) + self.groupBox_2.setFont(font) + self.groupBox_2.setObjectName("groupBox_2") + self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.groupBox_2) + self.verticalLayout_6.setObjectName("verticalLayout_6") + self.appdata_check = QtWidgets.QCheckBox(parent=self.groupBox_2) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + self.appdata_check.setFont(font) + self.appdata_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.appdata_check.setObjectName("appdata_check") + self.verticalLayout_6.addWidget(self.appdata_check) + self.media_check = QtWidgets.QCheckBox(parent=self.groupBox_2) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + self.media_check.setFont(font) + self.media_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.media_check.setObjectName("media_check") + self.verticalLayout_6.addWidget(self.media_check) + self.ids_check = QtWidgets.QCheckBox(parent=self.groupBox_2) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + self.ids_check.setFont(font) + self.ids_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.ids_check.setObjectName("ids_check") + self.verticalLayout_6.addWidget(self.ids_check) + self.verticalLayout_3.addWidget(self.groupBox_2) + self.groupBox = QtWidgets.QGroupBox(parent=self.steps) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth()) + self.groupBox.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(11) + font.setBold(True) + self.groupBox.setFont(font) + self.groupBox.setObjectName("groupBox") + self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox) + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.media_checked = QtWidgets.QCheckBox(parent=self.groupBox) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.media_checked.setFont(font) + self.media_checked.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.media_checked.setObjectName("media_checked") + self.verticalLayout_5.addWidget(self.media_checked) + self.media_edited_check = QtWidgets.QCheckBox(parent=self.groupBox) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.media_edited_check.setFont(font) + self.media_edited_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.media_edited_check.setObjectName("media_edited_check") + self.verticalLayout_5.addWidget(self.media_edited_check) + self.app_created = QtWidgets.QCheckBox(parent=self.groupBox) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.app_created.setFont(font) + self.app_created.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.app_created.setObjectName("app_created") + self.verticalLayout_5.addWidget(self.app_created) + self.btn_copy_adis_command = QtWidgets.QPushButton(parent=self.groupBox) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.btn_copy_adis_command.setFont(font) + self.btn_copy_adis_command.setStatusTip("") + self.btn_copy_adis_command.setWhatsThis("") + self.btn_copy_adis_command.setAccessibleDescription("") + self.btn_copy_adis_command.setAutoFillBackground(False) + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap("c:\\Users\\aky547\\GitHub\\SemesterapparatsManager\\src\\ui\\../../../../../../.designer/backup/icons/information.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.btn_copy_adis_command.setIcon(icon1) + self.btn_copy_adis_command.setCheckable(False) + self.btn_copy_adis_command.setChecked(False) + self.btn_copy_adis_command.setAutoDefault(False) + self.btn_copy_adis_command.setObjectName("btn_copy_adis_command") + self.verticalLayout_5.addWidget(self.btn_copy_adis_command) + self.verticalLayout_3.addWidget(self.groupBox) + self.verticalLayout_4.addWidget(self.steps) + self.verticalLayout.addWidget(self.frame_creation_progress) + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(parent=MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1590, 22)) + self.menubar.setObjectName("menubar") + self.menuDatei = QtWidgets.QMenu(parent=self.menubar) + self.menuDatei.setObjectName("menuDatei") + self.menuEinstellungen = QtWidgets.QMenu(parent=self.menubar) + self.menuEinstellungen.setObjectName("menuEinstellungen") + self.menuHelp = QtWidgets.QMenu(parent=self.menubar) + self.menuHelp.setObjectName("menuHelp") + MainWindow.setMenuBar(self.menubar) + self.statusBar = QtWidgets.QStatusBar(parent=MainWindow) + self.statusBar.setObjectName("statusBar") + MainWindow.setStatusBar(self.statusBar) + self.actionBeenden = QtGui.QAction(parent=MainWindow) + self.actionBeenden.setMenuRole(QtGui.QAction.MenuRole.QuitRole) + self.actionBeenden.setShortcutVisibleInContextMenu(True) + self.actionBeenden.setObjectName("actionBeenden") + self.actionEinstellungen = QtGui.QAction(parent=MainWindow) + self.actionEinstellungen.setShortcutVisibleInContextMenu(True) + self.actionEinstellungen.setObjectName("actionEinstellungen") + self.actionDokumentation = QtGui.QAction(parent=MainWindow) + self.actionDokumentation.setShortcutContext(QtCore.Qt.ShortcutContext.ApplicationShortcut) + self.actionDokumentation.setObjectName("actionDokumentation") + self.actionAbout = QtGui.QAction(parent=MainWindow) + self.actionAbout.setMenuRole(QtGui.QAction.MenuRole.AboutRole) + self.actionAbout.setObjectName("actionAbout") + self.actionDokumentation_lokal = QtGui.QAction(parent=MainWindow) + self.actionDokumentation_lokal.setObjectName("actionDokumentation_lokal") + self.menuDatei.addAction(self.actionBeenden) + self.menuEinstellungen.addAction(self.actionEinstellungen) + self.menuHelp.addAction(self.actionDokumentation_lokal) + self.menuHelp.addAction(self.actionAbout) + self.menubar.addAction(self.menuDatei.menuAction()) + self.menubar.addAction(self.menuEinstellungen.menuAction()) + self.menubar.addAction(self.menuHelp.menuAction()) + self.label_9.setBuddy(self.prof_tel_nr) + self.label_3.setBuddy(self.prof_title) + self.label_2.setBuddy(self.drpdwn_app_nr) + self.label_8.setBuddy(self.prof_mail) + self.label_10.setBuddy(self.app_fach) + self.label_12.setBuddy(self.prof_id_adis) + self.label_13.setBuddy(self.apparat_id_adis) + self.label_4.setBuddy(self.drpdwn_prof_name) + self.label_5.setBuddy(self.app_name) + self.label_6.setBuddy(self.sem_year) + + self.retranslateUi(MainWindow) + self.tabWidget.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + MainWindow.setTabOrder(self.drpdwn_app_nr, self.drpdwn_prof_name) + MainWindow.setTabOrder(self.drpdwn_prof_name, self.prof_mail) + MainWindow.setTabOrder(self.prof_mail, self.prof_tel_nr) + MainWindow.setTabOrder(self.prof_tel_nr, self.app_name) + MainWindow.setTabOrder(self.app_name, self.app_fach) + MainWindow.setTabOrder(self.app_fach, self.sem_sommer) + MainWindow.setTabOrder(self.sem_sommer, self.sem_winter) + MainWindow.setTabOrder(self.sem_winter, self.sem_year) + MainWindow.setTabOrder(self.sem_year, self.check_eternal_app) + MainWindow.setTabOrder(self.check_eternal_app, self.btn_add_document) + MainWindow.setTabOrder(self.btn_add_document, self.btn_open_document) + MainWindow.setTabOrder(self.btn_open_document, self.check_file) + MainWindow.setTabOrder(self.check_file, self.check_send_mail) + MainWindow.setTabOrder(self.check_send_mail, self.btn_apparat_save) + MainWindow.setTabOrder(self.btn_apparat_save, self.btn_apparat_apply) + MainWindow.setTabOrder(self.btn_apparat_apply, self.chkbx_show_del_media) + MainWindow.setTabOrder(self.chkbx_show_del_media, self.btn_reserve) + MainWindow.setTabOrder(self.btn_reserve, self.select_action_box) + MainWindow.setTabOrder(self.select_action_box, self.prof_id_adis) + MainWindow.setTabOrder(self.prof_id_adis, self.apparat_id_adis) + MainWindow.setTabOrder(self.apparat_id_adis, self.automation_add_selected_books) + MainWindow.setTabOrder(self.automation_add_selected_books, self.saveandcreate) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "Semesterapparatsmanagement")) + self.create_document.setToolTip(_translate("MainWindow", "Erstellt die Übersicht, welche am Regal ausgehängt werden kann")) + self.create_document.setText(_translate("MainWindow", "Übersicht erstellen")) + self.create_new_app.setText(_translate("MainWindow", "neu. App anlegen")) + self.cancel_active_selection.setText(_translate("MainWindow", "Auswahl abbrechen")) + self.tableWidget_apparate.setSortingEnabled(False) + item = self.tableWidget_apparate.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "AppNr")) + item = self.tableWidget_apparate.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "App Name")) + item = self.tableWidget_apparate.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Professor")) + item = self.tableWidget_apparate.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "gültig bis")) + item = self.tableWidget_apparate.horizontalHeaderItem(4) + item.setText(_translate("MainWindow", "Dauerapparat")) + item = self.tableWidget_apparate.horizontalHeaderItem(5) + item.setText(_translate("MainWindow", "KontoNr")) + self.chkbx_show_del_media.setText(_translate("MainWindow", "gel. Medien anzeigen")) + self.btn_reserve.setText(_translate("MainWindow", "im Apparat?")) + self.label_info.setText(_translate("MainWindow", "Medien werden hinzugefügt")) + self.progress_label.setText(_translate("MainWindow", "Medium x/y")) + self.label_20.setText(_translate("MainWindow", "Medien werden geprüft")) + self.avail_status.setText(_translate("MainWindow", "TextLabel")) + self.automation_add_selected_books.setText(_translate("MainWindow", "Ausgewählte als verfügbar markieren")) + self.tableWidget_apparat_media.setSortingEnabled(True) + item = self.tableWidget_apparat_media.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Buchtitel")) + item.setToolTip(_translate("MainWindow", "Es kann sein, dass der Buchtitel leer ist, dies kommt vor, wenn der Titel nicht passend formatiert ist")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Signatur")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Auflage")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Autor")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(4) + item.setText(_translate("MainWindow", "im Apparat?")) + item.setToolTip(_translate("MainWindow", "Diese Angabe ist nicht zuverlässig. Ist das ❌ vorhanden, kann das Medium im Apparat sein, aber aufgrund eines Bugs nicht gefunden worden")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(5) + item.setText(_translate("MainWindow", "Vorgemerkt")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(6) + item.setText(_translate("MainWindow", "Link")) + self.label.setText(_translate("MainWindow", " Medienliste")) + self.app_group_box.setTitle(_translate("MainWindow", "Apparatsdetails")) + item = self.document_list.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Dokumentname")) + item = self.document_list.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Dateityp")) + item = self.document_list.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Neu?")) + item = self.document_list.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "path")) + self.appname_mand.setText(_translate("MainWindow", "*")) + self.profname_mand.setText(_translate("MainWindow", "*")) + self.fach_mand.setText(_translate("MainWindow", "*")) + self.btn_apparat_apply.setText(_translate("MainWindow", "Aktualisieren")) + self.label_9.setText(_translate("MainWindow", "Tel")) + self._mand.setText(_translate("MainWindow", "*")) + self.check_eternal_app.setText(_translate("MainWindow", "Dauerapparat")) + self.sem_sommer.setText(_translate("MainWindow", "Sommer")) + self.drpdwn_prof_name.setToolTip(_translate("MainWindow", "Nachname, Vorname")) + self.mail_mand.setText(_translate("MainWindow", "*")) + self.label_3.setStatusTip(_translate("MainWindow", "sdvosdvsdv")) + self.label_3.setText(_translate("MainWindow", "Prof. Titel")) + self.label_2.setText(_translate("MainWindow", "Apparatsnummer")) + self.label_8.setText(_translate("MainWindow", "Mail")) + self.label_10.setText(_translate("MainWindow", "Fach")) + self.label_12.setText(_translate("MainWindow", "Prof-ID-aDIS")) + self.label_13.setText(_translate("MainWindow", "Apparat-ID-aDIS")) + self.sem_year.setPlaceholderText(_translate("MainWindow", "2023")) + self.check_send_mail.setText(_translate("MainWindow", "Mail senden")) + self.sem_winter.setText(_translate("MainWindow", "Winter")) + self.label_4.setText(_translate("MainWindow", "Prof. Name")) + self.telnr_mand.setText(_translate("MainWindow", "*")) + self.btn_apparat_save.setText(_translate("MainWindow", "Speichern")) + self.label_5.setText(_translate("MainWindow", "Apparatsname")) + self.label_6.setText(_translate("MainWindow", "Semester")) + self.valid_check_profname.setStatusTip(_translate("MainWindow", "Format: Nachname, Vorname")) + self.valid_check_mail.setStatusTip(_translate("MainWindow", "mail@irgendwas.wasanderes")) + self.saveandcreate.setText(_translate("MainWindow", "Speichern und anlegen")) + self.btn_add_document.setText(_translate("MainWindow", "Dokument hinzufügen")) + self.btn_open_document.setText(_translate("MainWindow", "Dokument öffnen")) + self.check_file.setToolTip(_translate("MainWindow", "Abhängig von der Anzahl der Medien kann die Suche sehr lange dauern")) + self.check_file.setText(_translate("MainWindow", "Medien aus Dokument\n" +" hinzufügen")) + self.btn_extract_data_from_document.setToolTip(_translate("MainWindow", "Die Apparatsdetails werden aus dem Dokument gelesen und eingetragen\n" +"Einige Angaben müssen ggf angepasst werden")) + self.btn_extract_data_from_document.setText(_translate("MainWindow", "Daten aus Dokument\n" +"übernehmen")) + self.add_medium.setText(_translate("MainWindow", "Medien hinzufügen")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.createApparat), _translate("MainWindow", "Anlegen")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.search_statistics), _translate("MainWindow", "Suchen / Statistik")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.elsatab), _translate("MainWindow", "ELSA")) + self.label_21.setText(_translate("MainWindow", "Aktion:")) + self.select_action_box.setItemText(0, _translate("MainWindow", "Nutzer anlegen")) + self.select_action_box.setItemText(1, _translate("MainWindow", "Nutzer bearbeiten")) + self.select_action_box.setItemText(2, _translate("MainWindow", "Lehrperson bearbeiten")) + self.admin_action.setTitle(_translate("MainWindow", "GroupBox")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.admin), _translate("MainWindow", "Admin")) + self.groupBox_2.setTitle(_translate("MainWindow", "Software")) + self.appdata_check.setText(_translate("MainWindow", "Apparatsdaten eingegeben")) + self.media_check.setText(_translate("MainWindow", "Medien hinzugefügt / importiert")) + self.ids_check.setText(_translate("MainWindow", "Prof-ID und Apparat-ID eingetragen")) + self.groupBox.setTitle(_translate("MainWindow", "aDIS")) + self.media_checked.setText(_translate("MainWindow", "Medien geprüft")) + self.media_edited_check.setText(_translate("MainWindow", "Medien bearbeitet")) + self.app_created.setText(_translate("MainWindow", "Apparat angelegt")) + self.btn_copy_adis_command.setToolTip(_translate("MainWindow", "Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren")) + self.btn_copy_adis_command.setText(_translate("MainWindow", " aDIS Abfrage in Zwischenablage kopieren")) + self.menuDatei.setTitle(_translate("MainWindow", "Datei")) + self.menuEinstellungen.setTitle(_translate("MainWindow", "Bearbeiten")) + self.menuHelp.setTitle(_translate("MainWindow", "Help")) + self.actionBeenden.setText(_translate("MainWindow", "Beenden")) + self.actionBeenden.setShortcut(_translate("MainWindow", "Ctrl+Q")) + self.actionEinstellungen.setText(_translate("MainWindow", "Einstellungen")) + self.actionEinstellungen.setShortcut(_translate("MainWindow", "Alt+S")) + self.actionDokumentation.setText(_translate("MainWindow", "Dokumentation (online)")) + self.actionDokumentation.setShortcut(_translate("MainWindow", "F1")) + self.actionAbout.setText(_translate("MainWindow", "About")) + self.actionDokumentation_lokal.setText(_translate("MainWindow", "Dokumentation (lokal)")) + self.actionDokumentation_lokal.setShortcut(_translate("MainWindow", "F1")) diff --git a/src/ui/userInterface.py b/src/ui/userInterface.py index dde4ee6..d2ad1d5 100644 --- a/src/ui/userInterface.py +++ b/src/ui/userInterface.py @@ -6,7 +6,8 @@ import sys import tempfile import webbrowser from pathlib import Path -from typing import Any +from typing import Any, Union + from natsort import natsorted from PyQt6 import QtCore, QtGui, QtWidgets from PyQt6.QtCore import QThread @@ -25,6 +26,7 @@ from src.logic import ( BookData, csv_to_list, word_to_semap, + SemapDocument, Prof, Apparat, ) @@ -87,6 +89,9 @@ class Ui(Ui_Semesterapparat): self.check_file.clicked.connect( # type:ignore self.btn_check_file_threaded ) # default: self.add_media_from_file + self.btn_extract_data_from_document.clicked.connect( # type:ignore + self.import_data_from_document + ) 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 @@ -136,7 +141,7 @@ class Ui(Ui_Semesterapparat): self.prof_tel_nr.setValidator( QtGui.QRegularExpressionValidator(QtCore.QRegularExpression(r"^\d{3,14}")) ) - # #print(self.prof_tel_nr.maxLength()) + # #logger.debug(self.prof_tel_nr.maxLength()) self.app_fach.setValidator( # validator to allow typing in the app_fach field QtGui.QRegularExpressionValidator( QtCore.QRegularExpression(r"[a-zA-Z0-9\s\W]+") @@ -154,7 +159,7 @@ class Ui(Ui_Semesterapparat): ) self.tableWidget_apparate.doubleClicked.connect(self.load_app_data) # type:ignore - # #print(f"user:{self.active_user}") + # #logger.debug(f"user:{self.active_user}") userrole = self.db.getRole(self.active_user) # hide admin interface when non-admin is logged in if userrole == "admin": @@ -201,7 +206,7 @@ class Ui(Ui_Semesterapparat): self.validate_thread.start() self.add_medium.setEnabled(False) self.docu = DocumentationThread() - self.docu.start() + self.actionDokumentation_lokal.triggered.connect(self.open_documentation) # type:ignore # get all current apparats and cache them in a list @@ -251,6 +256,8 @@ class Ui(Ui_Semesterapparat): self.steps.hide() + self.valid_check_semester.clicked.connect(self.display_valid_semester) # type:ignore + def create_doc(self): result = self.confirm_popup( "Mit dem Klick auf Okay wird eine Übersicht aller aktiven Semesterapparate erstellt und an den FollowME Drucker gesendet. Es kann bis zu 10 Minuten dauern, bis das document im Drucker angezeigt wird", @@ -258,14 +265,14 @@ class Ui(Ui_Semesterapparat): ) logger.debug(f"Result: {result}") if result == 1: - # print("Creating document") + # logger.debug("Creating document") apparats = self.apparats apps = [] for apparat in apparats: prof = self.db.getProf(apparat[2]) data = (apparat[4], f"{prof.lastname} ({apparat[1]})") apps.append(data) - # print(apps) + # logger.debug(apps) logger.info("Using apparats: {}", apps) doc = SemesterDocument( semester=Semester().value, @@ -350,6 +357,8 @@ class Ui(Ui_Semesterapparat): def open_documentation(self): logger.info("Opening Documentation") + if not self.docu.isRunning(): + self.docu.start() webbrowser.open("http://localhost:8000") def update_calendar(self, data): @@ -372,7 +381,7 @@ class Ui(Ui_Semesterapparat): statistics.updateCalendar.connect(self.update_calendar) stats_layout.addWidget(statistics) - # #print("searchpage") + # #logger.debug("searchpage") if self.tabWidget.currentIndex() == 0: # Apparate # clear all entries from the table self.tableWidget_apparate.setRowCount(0) @@ -390,7 +399,7 @@ class Ui(Ui_Semesterapparat): widget.deleteLater() elsa_layout.addWidget(ElsaDialog()) - # print("added") + # logger.debug("added") pass def generateSemester(self, today=False): @@ -433,9 +442,9 @@ class Ui(Ui_Semesterapparat): self.prof_mail.setText(appdata.prof.mail) self.prof_tel_nr.setText(appdata.prof.telnr) self.app_name.setText(appdata.apparat.name) - # #print("changing dropdown app_fach from '' to ", appdata.app_fach) + # #logger.debug("changing dropdown app_fach from '' to ", appdata.app_fach) self.app_fach.setCurrentText(appdata.apparat.subject) - # #print("changed dropdown app_fach to ", self.app_fach.currentText()) + # #logger.debug("changed dropdown app_fach to ", self.app_fach.currentText()) self.sem_year.setText(appdata.apparat.get_semester.split(" ")[1]) match appdata.apparat.get_semester.split(" ")[0]: case "SoSe": @@ -500,7 +509,7 @@ class Ui(Ui_Semesterapparat): return popup.result() def thread_check(self): - # #print("Thread started") + # #logger.debug("Thread started") 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) @@ -564,22 +573,24 @@ class Ui(Ui_Semesterapparat): self.__setValidState(self.valid_check_app_fach, 0, self.fach_mand, 4) def validate_semester(self): - if ( - self.app_group_box.isEnabled() - and ( - (self.sem_sommer.isChecked() or self.sem_winter.isChecked()) - and self.sem_year.text() != "" - and len(self.sem_year.text()) - >= 2 # check if the year is at least 2 digits long - ) - or self.check_eternal_app.isChecked() - ): + valid = (self.sem_sommer.isChecked() or self.sem_winter.isChecked()) and len( + self.sem_year.text() + ) >= 2 + if valid or self.check_eternal_app.isChecked(): self.__setValidState(self.valid_check_semester, 1, self._mand, 5) self.check_eternal_app.setEnabled(True) else: self.__setValidState(self.valid_check_semester, 0, self._mand, 5) self.check_eternal_app.setEnabled(False) + def display_valid_semester(self): + print(f""" + Semester: {self.sem_year.text()} + Sommer: {self.sem_sommer.isChecked()} + Winter: {self.sem_winter.isChecked()} + Eternal: {self.check_eternal_app.isChecked()} + """) + def change_state(self, index, state): global valid_input valid_input = list(valid_input) @@ -706,12 +717,12 @@ class Ui(Ui_Semesterapparat): self.drpdwn_prof_name.clear() # set drop down menu for apparat numbers to only available numbers taken_app_nrs = self.db.getUnavailableApparatNumbers() - self.drpdwn_app_nr.addItems([str(i) for i in APP_NRS if i not in taken_app_nrs]) + self.drpdwn_app_nr.addItems([str(i) for i in APP_NRS if i not in taken_app_nrs]) # type:ignore valid_input = (0, 0, 0, 0, 0, 0) self.populate_prof_dropdown() - def update_progress_label(self, curr, total): + def update_progress_label(self, curr: int, total: int): text = f"Medium {curr}/{total}" logger.info(text) self.progress_label.setText(text) @@ -769,7 +780,7 @@ class Ui(Ui_Semesterapparat): bookGrabber.start() while bookGrabber.isRunning(): - # #print("waiting for thread to finish") + # #logger.debug("waiting for thread to finish") QtWidgets.QApplication.processEvents() # self.__clear_fields() @@ -814,7 +825,7 @@ class Ui(Ui_Semesterapparat): # thread = QThread() appnumber = self.active_apparat - # #print(links) + # #logger.debug(links) self.availChecker = AvailChecker(links, appnumber, books=books) # availcheck.moveToThread(thread) # availcheck.finished.connect(thread.quit) @@ -863,7 +874,7 @@ class Ui(Ui_Semesterapparat): app_id, prof_id, deleted ) - # # #print(books) + # # #logger.debug(books) # take the dataclass from the tuple # booklist:list[BookData]=[book[0] for book in books] self.tableWidget_apparat_media.setRowCount(0) @@ -872,7 +883,7 @@ class Ui(Ui_Semesterapparat): book_data = book["bookdata"] availability = book["available"] # bd = BookData().from_string(book) - # # #print(bd, type(bd)) + # # #logger.debug(bd, type(bd)) # create a new row below the last one self.tableWidget_apparat_media.insertRow( self.tableWidget_apparat_media.rowCount() @@ -966,11 +977,11 @@ class Ui(Ui_Semesterapparat): self.drpdwn_prof_name.addItem(prof) def add_document(self): - # #print("Add document") + # #logger.debug("Add document") picker = FilePicker() files = picker.pick_files() for file in files: - # #print(file) + # #logger.debug(file) filename = file.split("/")[-1] filetype = filename.split(".")[-1] self.document_list.insertRow(0) @@ -1022,7 +1033,7 @@ class Ui(Ui_Semesterapparat): dialog = QtWidgets.QDialog() frame = parsed_titles_ui() frame.setupUi(dialog) - dialogger.show() + dialog.show() frame.signatures = signatures frame.populate_table() frame.progressBar.setMaximum(len(signatures)) @@ -1042,7 +1053,7 @@ class Ui(Ui_Semesterapparat): else: # if file is selected, check for books in the file if self.document_list.currentRow() != -1: - # #print("File selected") + # #logger.debug("File selected") file = self.document_list.item( self.document_list.currentRow(), 3 ).text() @@ -1096,10 +1107,53 @@ class Ui(Ui_Semesterapparat): bookdata=book, app_id=app_id, prof_id=prof_id ) self.update_app_media_list() - # #print(len(signatures)) + # #logger.debug(len(signatures)) + + def extract_document_data(self) -> Union[None, list[str], SemapDocument]: + file_type = self.document_list.item(self.document_list.currentRow(), 1).text() + file_location = self.document_list.item( + self.document_list.currentRow(), 3 + ).text() + file_name = self.document_list.item(self.document_list.currentRow(), 0).text() + file = file_location + logger.info("File selected: {}, {}", file_name, file_location) + if file_location == "Database": + # create warning, then return + self.confirm_popup( + "Dateien aus der Datenbank werden nicht unterstützt!", + title="Fehler", + ) + return None + if file_type == "pdf": + # Todo: implement parser here + self.confirm_popup("PDF Dateien werden nicht unterstützt!", title="Fehler") + return + if file_type == "csv": + signatures = csv_to_list(file) + # add the data to the database + return signatures + if file_type == "docx": + data = word_to_semap(file) + logger.info("Converted data from semap file") + logger.debug("Got the data: {}", data) + + return data + + def import_data_from_document(self): + global valid_input + data = self.extract_document_data() + if data is None: + return + if isinstance(data, list): + return + + self.prof_mail.setText(data.mail) + self.prof_tel_nr.setText(str(data.phoneNumber)) + self.app_name.setText(data.title) + self.app_fach.setCurrentText(data.subject) def btn_check_file_threaded(self): - # #print("Checking file") + # #logger.debug("Checking file") # get active app_id and prof_id self.tableWidget_apparate.setEnabled(False) self.tableWidget_apparate.setToolTip( @@ -1109,18 +1163,25 @@ class Ui(Ui_Semesterapparat): logger.debug(self.profdata) prof_id = self.db.getProfId(self.profdata) - logger.debug(prof_id) + logger.debug("Prof id: {}", prof_id) # check if apparat in database - + if prof_id is None: + prof = Prof( + fullname=self.drpdwn_prof_name.currentText(), + telnr=self.prof_tel_nr.text(), + mail=self.prof_mail.text(), + firstname=self.drpdwn_prof_name.currentText().split(", ")[1], + lastname=self.drpdwn_prof_name.currentText().split(", ")[0], + ) + self.db.createProf(prof) # if app_id not in database, create apparat - created = False if not self.db.checkApparatExistsById(app_id): logger.info("Apparat does not exist, creating new apparat") # create apparat - # #print("Creating apparat") + # #logger.debug("Creating apparat") if not self.btn_save_apparat(False): return - created = True + if self.document_list.rowCount() == 0: logger.info("No file selected") self.tableWidget_apparate.setEnabled(True) @@ -1128,48 +1189,27 @@ class Ui(Ui_Semesterapparat): return else: # if file is selected, check for books in the file - # #print("File selected") - file_type = self.document_list.item( - self.document_list.currentRow(), 1 - ).text() - file_location = self.document_list.item( - self.document_list.currentRow(), 3 - ).text() - file_name = self.document_list.item( - self.document_list.currentRow(), 0 - ).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 - self.confirm_popup( - "PDF Dateien werden nicht unterstützt!", title="Fehler" - ) - return - if file_type == "csv": - signatures = csv_to_list(file) - # add the data to the database - if file_type == "docx": - data = word_to_semap(file) - logger.info("Converted data from semap file") - logger.debug("Got the data: {}", data) - signatures = data.signatures - logger.info("Got the signatures: {}", signatures) + # #logger.debug("File selected") + if prof_id is None: prof_id = self.db.getProfId(self.profdata) - # print("Prof ID is None", prof_id) - autoGrabber = BookGrabber(self.active_apparat) + # logger.debug("Prof ID is None", prof_id) + document = self.extract_document_data() + if document is None: + logger.error("Document is None") + elif isinstance(document, SemapDocument): + signatures = document.signatures + else: + signatures = document + autoGrabber = BookGrabber() autoGrabber.add_values( - mode="ARRAY", app_id=app_id, prof_id=prof_id, data=signatures + mode="ARRAY", + app_id=int(app_id), + prof_id=int(prof_id), + data=signatures, + any_book=True, + exact=True, ) self.label_info.show() self.progress_label.show() @@ -1178,15 +1218,13 @@ class Ui(Ui_Semesterapparat): # self.autoGrabber.finished.connect(self.autoGrabber.deleteLater) autoGrabber.finished.connect(self.hide_progress_label) autoGrabber.finished.connect(self.unlock_apparate) - autoGrabber.updateSignal.connect(self.update_progress_label) # worker.finished.connect(worker.deleteLater) autoGrabber.start() - while autoGrabber.isRunning(): - QtWidgets.QApplication.processEvents() + self.bookGrabber.append(autoGrabber) # refresh book table - self.update_app_media_list() + logger.debug("Finished adding media") # end of thread # self.autoGrabber.exit() # self.__clear_fields() @@ -1271,7 +1309,7 @@ class Ui(Ui_Semesterapparat): pid=appd.prof.fullname, ) if clear_fields: - # #print("clearing fields") + # #logger.debug("clearing fields") self.__clear_fields() return True @@ -1398,7 +1436,7 @@ class Ui(Ui_Semesterapparat): appnr = self.tableWidget_apparate.item(tableposition, 0).text() if reminder.result() == QtWidgets.QDialogger.DialogCode.Accepted: data = reminder.return_message() - # #print(data) + # #logger.debug(data) self.db.addMessage( data, self.active_user, @@ -1418,7 +1456,7 @@ class Ui(Ui_Semesterapparat): def open_reminder(self): selected_date = self.calendarWidget.selectedDate().toString("yyyy-MM-dd") - # # #print(selected_date) + # # #logger.debug(selected_date) messages = self.db.getMessages(selected_date) if messages == []: return @@ -1431,13 +1469,13 @@ class Ui(Ui_Semesterapparat): ) def open_settings(self): - # print(settings.dict()) + # logger.debug(settings.dict()) settingsUI = Settings(self.active_user) settingsUI.exec() if settingsUI.result() == QtWidgets.QDialogger.DialogCode.Accepted: settingsUI.save() - # print(settings.dict()) + # logger.debug(settings.dict()) # self.reload() @@ -1563,7 +1601,7 @@ class Ui(Ui_Semesterapparat): signature=signature, prof_id=self.db.getProfId(self.profdata), ) - # print(medium.adis_idn, medium.signature) + # logger.debug(medium.adis_idn, medium.signature) def edit_medium(self): book = self.tableWidget_apparat_media.item( @@ -1590,10 +1628,10 @@ class Ui(Ui_Semesterapparat): widget.exec() if widget.result() == QtWidgets.QDialogger.DialogCode.Accepted: data = bookedit.get_data() - # #print(data) + # #logger.debug(data) self.db.updateBookdata(bookdata=data, book_id=book_id) # self.db.update_bookdata(data) - # #print("accepted") + # #logger.debug("accepted") self.update_app_media_list() else: return @@ -1617,7 +1655,7 @@ class Ui(Ui_Semesterapparat): ) message = f'Soll das Medium "{self.tableWidget_apparat_media.item(self.tableWidget_apparat_media.currentRow(), 0).text()}" wirklich gelöscht werden?' state = self.confirm_popup(message, title="Löschen?") - # #print(state) + # #logger.debug(state) if state == 1: self.db.deleteBook(book_id) self.update_app_media_list() @@ -1629,7 +1667,7 @@ class Ui(Ui_Semesterapparat): for r in ranges: for row in range(r.topRow(), r.bottomRow() + 1): rows.append(row) - # #print(rows) + # #logger.debug(rows) message = f"Sollen die {len(rows)} Medien wirklich gelöscht werden?" state = self.confirm_popup(message, title="Löschen?") if state == 1: @@ -1649,12 +1687,12 @@ class Ui(Ui_Semesterapparat): # return data from dialog if ok is pressed if framework.result() == QtWidgets.QDialogger.DialogCode.Accepted: data = framework.get_data() - # #print(data) + # #logger.debug(data) # return data selected_apparat_id = self.tableWidget_apparate.item( self.tableWidget_apparate.currentRow(), 0 ).text() - # #print(selected_apparat_id) + # #logger.debug(selected_apparat_id) self.db.setNewSemesterDate( selected_apparat_id, data["semester"], dauerapp=data["dauerapp"] @@ -1725,7 +1763,7 @@ class Ui(Ui_Semesterapparat): ).text() message = f"Soll der Apparat {selected_apparat_id} wirklich gelöscht werden?" state = self.confirm_popup(message, title="Löschen?") - # #print(state) + # #logger.debug(state) logger.info("Result state: {}", state) if state == 1: logger.debug("Deleting apparat {}", selected_apparat_id) @@ -1737,7 +1775,7 @@ class Ui(Ui_Semesterapparat): self.apparats.remove(apparat) break self.old_apparats = self.apparats - # #print(self.apparats) + # #logger.debug(self.apparats) # remove the row from the table self.tableWidget_apparate.removeRow(self.tableWidget_apparate.currentRow()) # send mail to prof @@ -1745,8 +1783,8 @@ class Ui(Ui_Semesterapparat): def launch_gui(): - # #print("trying to login") - # #print("checking if database available") + # #logger.debug("trying to login") + # #logger.debug("checking if database available") logger.info("Starting login dialog") app = QtWidgets.QApplication(sys.argv) @@ -1758,11 +1796,11 @@ def launch_gui(): if ui.lresult == 1: # if login is successful, open main window # show login dialog - # #print(ui.lusername) + # #logger.debug(ui.lusername) MainWindow = QtWidgets.QMainWindow() aui = Ui(MainWindow, username=ui.lusername) - # #print(aui.active_user) + # #logger.debug(aui.active_user) MainWindow.show() # atexit.register() atexit.register(tempdelete) @@ -1779,7 +1817,7 @@ def launch_gui(): if __name__ == "__main__": - # #print("This is the main window") + # #logger.debug("This is the main window") # app = QtWidgets.QApplication(sys.argv) # window = MainWindow() # app.exec() diff --git a/src/ui/widgets/searchPage.py b/src/ui/widgets/searchPage.py index 68d9c48..5606d84 100644 --- a/src/ui/widgets/searchPage.py +++ b/src/ui/widgets/searchPage.py @@ -83,7 +83,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog): apparats.append(self.tableWidget.item(row.row(), 1).text()) for apparat in apparats: apparat_id = self.db.getApparatId(apparat) - self.db.restoreApparat(apparat_id) + self.db.restoreApparat(apparat_id, apparat) # remove the red color from the row # get row where the apparat is row = self.tableWidget.findItems(apparat, QtCore.Qt.MatchFlag.MatchExactly)[ diff --git a/src/utils/blob.py b/src/utils/blob.py index c28636a..f2c8070 100644 --- a/src/utils/blob.py +++ b/src/utils/blob.py @@ -1,4 +1,4 @@ -def create_blob(file): +def create_blob(file: str): """ Creates a blob from a file. """ diff --git a/src/utils/pickles.py b/src/utils/pickles.py index cb5a84f..e943a0d 100644 --- a/src/utils/pickles.py +++ b/src/utils/pickles.py @@ -1,9 +1,10 @@ import pickle +from typing import Any -def load_pickle(data): +def load_pickle(data: Any): return pickle.loads(data) -def dump_pickle(data): +def dump_pickle(data: Any): return pickle.dumps(data)