import os from PySide6 import QtCore, QtGui, QtWidgets from PySide6.QtCore import QDate from PySide6.QtGui import QRegularExpressionValidator from src import Icon from src.backend import Database, recreateElsaFile from src.logic import Prof, Semester, elsa_word_to_csv from src.shared.logging import log from src.ui.dialogs import ElsaAddEntry, popus_confirm from src.ui.widgets.filepicker import FilePicker from src.ui.widgets.graph import DataQtGraph from .widget_sources.elsa_maindialog_ui import Ui_Dialog class ElsaDialog(QtWidgets.QDialog, Ui_Dialog): def __init__(self): super().__init__() self.setupUi(self) self.table_elsa_list.setContextMenuPolicy( QtCore.Qt.ContextMenuPolicy.CustomContextMenu ) self.table_elsa_list.customContextMenuRequested.connect(self.elsa_context_menu) # elsa buttons Icon("semester", self.active_semester) Icon("today", self.elsa_date_today) self.create_frame_elsa.setEnabled(False) self.elsa_add_new.clicked.connect(self.add_new_elsa) self.elsa_cancel_create.clicked.connect(self.cancel_elsa_creation) self.elsa_save.clicked.connect(self.save_elsa) self.elsa_date_today.clicked.connect(self.generateTodayDateElsa) self.active_semester.clicked.connect(self.addSemester) self.elsa_update.clicked.connect(self.update_elsa) self.elsa_table.doubleClicked.connect(self.open_elsa) self.btn_add_document_elsa.clicked.connect(self.addDokumentElsa) self.check_file_elsa.clicked.connect(self.parseDokumentElsa) self.btn_open_document_elsa.clicked.connect(self.openDocumentElsa) self.quote_entry.clicked.connect(self.elsa_table_entry) self.quote_entry.setEnabled(False) self.newProf.hide() self.splitter = QtWidgets.QSplitter(QtCore.Qt.Orientation.Horizontal) self.splitter.addWidget(self.media_table) self.splitter.addWidget(self.statistics) self.results.layout().removeWidget(self.media_table) self.results.layout().removeWidget(self.statistics) self.results.layout().addWidget(self.splitter) self.elsa_statistics_table.setColumnCount(2) # set header to occupy the whole width and auto scale based on table width self.elsa_statistics_table.horizontalHeader().setStretchLastSection(True) self.elsa_statistics_table.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.ResizeMode.Stretch ) # if table size gets smaller, set horitzontal headers text to be left aligned self.elsa_statistics_table.horizontalHeader().setDefaultAlignment( QtCore.Qt.AlignmentFlag.AlignLeft ) # self.table_elsa_list. Icon("person", self.prof_icon) # validators # prof mail self.newProf_mail.setValidator( QRegularExpressionValidator( QtCore.QRegularExpression( r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}" ) ) ) self.newProf_telnr.setValidator(QtGui.QIntValidator()) self.newProf_telnr.setValidator( QtGui.QRegularExpressionValidator(QtCore.QRegularExpression(r"^\d{3,14}")) ) ##Variables self.db = Database() self.graph_data = {"x": [""], "y": [0]} self.createProf = False self.profs = self.getProfs() self.elsa_prof.addItems([prof[0] for prof in self.profs]) self.elsa_prof.addItem("") self.elsa_prof.setCurrentText("") # implement a check for the prof name. if name is not in list and has schema of lastname, firstname, show newProf frame self.elsa_prof.currentTextChanged.connect(self.checkProf) self.newProf_mail.textChanged.connect(self.checkProfData) self.newProf_telnr.textChanged.connect(self.checkProfData) self.newProf_title.textChanged.connect(self.checkProfData) self.loadFrame() log.info("Elsa Dialog loaded") # self.show() def checkProfData(self): if ( (self.newProf_mail.text() != "" and self.newProf_mail.hasAcceptableInput()) and self.newProf_title.text() != "" and ( self.newProf_telnr.text() != "" and self.newProf_telnr.hasAcceptableInput() ) ): self.elsa_save.setEnabled(True) self.elsa_save.setToolTip("") self.newProf_mail.setToolTip("") self.newProf_telnr.setToolTip("") else: self.elsa_save.setEnabled(False) self.elsa_save.setToolTip("Bitte erst Daten eingeben") self.newProf_mail.setToolTip("Bitte geben Sie eine gültige E-Mail ein") self.newProf_telnr.setToolTip( "Bitte geben Sie eine gültige Telefonnummer ein" ) def checkProf(self): if ( ", " in self.elsa_prof.currentText() and self.elsa_prof.currentText() not in [prof[0] for prof in self.profs] ): self.newProf.show() self.elsa_save.setEnabled(False) self.elsa_save.setToolTip("Bitte erst Daten eingeben") self.createProf = True else: self.newProf.hide() self.createProf = False self.elsa_save.setEnabled(True) self.elsa_save.setToolTip("") def getProfs(self): profs = self.db.getProfs() profs = [ ("{}, {}".format(prof.lastname, prof.firstname), prof.id) for prof in profs ] profs = list(set(profs)) profs.sort() return profs def elsa_context_menu(self, position): QtWidgets.QMenu() # TODO: add functions pass def elsa_table_entry(self): data = ElsaAddEntry() selected_row = self.table_elsa_list.currentRow() signature = self.table_elsa_list.item(selected_row, 10).text() mediatype = self.table_elsa_list.item(selected_row, 11).text() pages = self.table_elsa_list.item(selected_row, 7).text().strip() data.searchIdent.setText(signature) match mediatype: case "Monografien": data.btn_mono.click() case "Herausgeberwerke": data.btn_hg.click() case "Zeitschriftenaufsätze": data.btn_zs.click() if ";" in pages: data.search() else: data.search(pages=pages) data.exec() def add_new_elsa(self): self.create_frame_elsa.setEnabled(True) self.elsa_cancel_create.setEnabled(True) self.dokument_list_elsa.setRowCount(0) self.elsa_save.setEnabled(True) self.elsa_update.setEnabled(False) self.elsa_prof.setFocus() def cancel_elsa_creation(self): self.create_frame_elsa.setEnabled(False) self.elsa_cancel_create.setEnabled(False) self.elsa_prof.setCurrentText("") self.elsa_date.setText("") self.elsa_semester.setText("") self.dokument_list_elsa.setRowCount(0) self.table_elsa_list.setRowCount(0) self.quote_entry.setEnabled(False) self.elsa_save.setEnabled(False) self.elsa_update.setEnabled(False) self.seperateEntries.setChecked(False) def generateTodayDateElsa(self): self.elsa_date.setText(QDate.currentDate().toString("dd.MM.yyyy")) def addSemester(self): self.elsa_semester.setText(Semester().value) def update_elsa(self): prof = self.elsa_prof.currentText() date = self.elsa_date.text() semester = self.elsa_semester.text() elsa_id = self.db.getElsaId(prof, semester, date) if elsa_id is None: return self.db.updateElsaApparat(elsa_id, prof, semester, date) self.elsa_update.setEnabled(False) self.cancel_elsa_creation() def confirm_popup(self, message: str, title: str): popup = popus_confirm(title=title) popup.textEdit.setReadOnly(True) popup.textEdit.setText(message) popup.exec() return popup.result() def save_elsa(self): if ( self.elsa_prof.currentText() == "" or self.elsa_semester.text() == "" or self.elsa_date.text() == "" ): # warning message self.confirm_popup("Bitte füllen Sie alle Felder aus", title="Fehler") return prof = self.elsa_prof.currentText() semester = self.elsa_semester.text() date = self.elsa_date.text() profdata = Prof( firstname=prof.split(", ")[1], lastname=prof.split(", ")[0], mail=self.newProf_mail.text(), telnr=self.newProf_telnr.text(), _title=self.newProf_title.text(), fullname=f"{prof.split(', ')[0]} {prof.split(', ')[1]}", ) prof_id = self.db.getProfId(profdata) log.debug(f"ProfData: {profdata}, id:{prof_id}") if prof_id is None: self.db.createProf(profdata) prof_id = self.db.getProfId(profdata) self.profs.append( "f{}, {}".format(profdata.lastname, profdata.firstname), prof_id ) elsa_id = self.db.createElsaApparat( date, prof_id, semester, ) if self.dokument_list_elsa.rowCount() > 0: files = [] for i in range(self.dokument_list_elsa.rowCount()): filename = self.dokument_list_elsa.item(i, 0).text() filetype = self.dokument_list_elsa.item(i, 1).text() file_path = self.dokument_list_elsa.item(i, 3).text() file = {"name": filename, "path": file_path, "type": filetype} files.append(file) self.db.insertElsaFile( files, elsa_id, ) log.info("Stored {} files in the database", len(files)) self.cancel_elsa_creation() self.refresh_elsa_table() self.elsa_prof.setCurrentText("") self.quote_entry.setEnabled(False) log.info("Saved apparat to database, id {}", elsa_id) def refresh_elsa_table(self): self.elsa_table.setRowCount(0) elsa_apparats = self.db.getElsaApparats() for apparat in elsa_apparats: self.insert_elsa_into_table(apparat) def insert_elsa_into_table(self, apparat): self.elsa_table.insertRow(0) date = apparat[1] semester = apparat[2] prof = self.db.getProfNameById(apparat[3]) self.elsa_table.setItem(0, 0, QtWidgets.QTableWidgetItem(prof)) self.elsa_table.setItem(0, 1, QtWidgets.QTableWidgetItem(date)) self.elsa_table.setItem(0, 2, QtWidgets.QTableWidgetItem(semester)) return (semester, 1) def open_elsa(self): prof = self.elsa_table.item(self.elsa_table.currentRow(), 0).text() log.info("prof", prof) date = self.elsa_table.item(self.elsa_table.currentRow(), 1).text() semester = self.elsa_table.item(self.elsa_table.currentRow(), 2).text() self.elsa_update.setEnabled(True) self.elsa_save.setEnabled(False) if self.elsa_prof.currentText() == prof and date == self.elsa_date.text(): log.debug("Same prof, stopping") return self.create_frame_elsa.setEnabled(True) self.dokument_list_elsa.setRowCount(0) self.table_elsa_list.setRowCount(0) self.elsa_cancel_create.setEnabled(True) # get elsa apparats, iterate over them and find the one where all matches elsa_apparats = self.db.getElsaApparats() elsa_id = None for apparat in elsa_apparats: if ( apparat[1] == date and apparat[2] == semester and apparat[3] == self.db.getProfId({"profname": prof}) ): elsa_id = apparat[0] break self.elsa_date.setText(date) self.elsa_semester.setText(semester) self.elsa_prof.setCurrentText(prof) log.info("Elsa ID is {}", elsa_id) if elsa_id is None: return documents = self.db.getElsaFiles(elsa_id) for document in documents: self.dokument_list_elsa.insertRow(0) self.dokument_list_elsa.setItem( 0, 0, QtWidgets.QTableWidgetItem(document[0]) ) self.dokument_list_elsa.setItem( 0, 1, QtWidgets.QTableWidgetItem(document[1]) ) self.dokument_list_elsa.setItem(0, 2, QtWidgets.QTableWidgetItem("❌")) self.dokument_list_elsa.setItem( 0, 3, QtWidgets.QTableWidgetItem("Database") ) scans = self.db.getElsaMedia(elsa_id) if scans == []: self.create_frame_elsa.setEnabled(True) for scan in scans: self.setElsaRow(scan) self.quote_entry.setEnabled(True) # self.cancel_elsa_creation() def setElsaRow(self, scan): self.table_elsa_list.insertRow(0) self.table_elsa_list.setItem( 0, 0, QtWidgets.QTableWidgetItem(scan["work_author"]) ) self.table_elsa_list.setItem( 0, 1, QtWidgets.QTableWidgetItem(scan["section_author"]) ) self.table_elsa_list.setItem(0, 2, QtWidgets.QTableWidgetItem(scan["year"])) self.table_elsa_list.setItem(0, 3, QtWidgets.QTableWidgetItem(scan["issue"])) self.table_elsa_list.setItem(0, 4, QtWidgets.QTableWidgetItem(scan["edition"])) self.table_elsa_list.setItem( 0, 5, QtWidgets.QTableWidgetItem(scan["work_title"]) ) self.table_elsa_list.setItem( 0, 6, QtWidgets.QTableWidgetItem(scan["chapter_title"]) ) self.table_elsa_list.setItem( 0, 7, QtWidgets.QTableWidgetItem(scan["pages"]), ) self.table_elsa_list.setItem(0, 8, QtWidgets.QTableWidgetItem(scan["location"])) self.table_elsa_list.setItem( 0, 9, QtWidgets.QTableWidgetItem(scan["publisher"]) ) self.table_elsa_list.setItem( 0, 10, QtWidgets.QTableWidgetItem(scan["signature"]) ) self.table_elsa_list.setItem(0, 11, QtWidgets.QTableWidgetItem(scan["type"])) def addDokumentElsa(self): picker = FilePicker() files = picker.pick_files() datalist = [] for file in files: data = {} filename = file.split("/")[-1] filetype = filename.split(".")[-1] self.dokument_list_elsa.insertRow(0) self.dokument_list_elsa.setItem(0, 0, QtWidgets.QTableWidgetItem(filename)) self.dokument_list_elsa.setItem(0, 1, QtWidgets.QTableWidgetItem(filetype)) self.dokument_list_elsa.setItem(0, 2, QtWidgets.QTableWidgetItem("*")) self.dokument_list_elsa.setItem(0, 3, QtWidgets.QTableWidgetItem(file)) # set tooltip of row 3 to the file path for each row self.dokument_list_elsa.item(0, 3).setToolTip(file) data["name"] = filename data["path"] = file data["type"] = filetype datalist.append(data) def parseDokumentElsa(self): if self.dokument_list_elsa.rowCount() == 0: return else: # get the file path of the selected file based on it's row row = self.dokument_list_elsa.currentRow() file = self.dokument_list_elsa.item(row, 3).text() file_location = file if file == "Database": filename = self.dokument_list_elsa.item(row, 0).text() filetype = self.dokument_list_elsa.item(row, 1).text() file = recreateElsaFile( filename=filename, filetype=filetype, open=False ) data, _ = elsa_word_to_csv(file) elsa_id = self.db.getElsaId( self.db.getProfId(Prof(fullname=self.elsa_prof.currentText())), self.elsa_semester.text(), self.elsa_date.text(), ) log.debug( f"elsa_id: {elsa_id}, prof: {self.elsa_prof.currentText()}, semester: {self.elsa_semester.text()}, date: {self.elsa_date.text()}" ) if file_location != "Database": self.db.insertElsaFile( [ { "name": file.split("/")[-1], "path": file, "type": file.split(".")[-1], } ], elsa_id, ) for row in data: if self.seperateEntries.isChecked(): if ";" in row["pages"]: count = row["pages"].split(";") for i in range(len(count)): row["pages"] = count[i] self.setElsaRow( row, ) self.db.addElsaMedia(row, elsa_id) else: self.setElsaRow(row) self.db.addElsaMedia(row, elsa_id) self.quote_entry.setEnabled(True) def openDocumentElsa(self): # open the selected document row = self.dokument_list_elsa.currentRow() location = self.dokument_list_elsa.item(row, 3).text() filetype = self.dokument_list_elsa.item(row, 1).text() filename = self.dokument_list_elsa.item(row, 0).text() if location == "Database": recreateElsaFile(filename, filetype, open=True) else: os.system(f"{filename}") def loadFrame(self): self.elsa_cancel_create.click() try: self.elsa_statistics.removeTab(1) except: log.debug("No tab to remove") self.elsa_table.setRowCount(0) elsa_apparats = self.db.getElsaApparats() # elsa_apparats = natsorted(elsa_apparats, key=lambda x: x[2], reverse=True) # x = semester, y = number of apparats for apparat in elsa_apparats: data = self.insert_elsa_into_table(apparat) semester = data[0] number = data[1] if semester not in self.graph_data["x"]: self.graph_data["x"].append(semester) self.graph_data["y"].append(number) else: index = self.graph_data["x"].index(semester) self.graph_data["y"][index] += number self.graph_data["x"].pop(0) self.graph_data["y"].pop(0) # generateMissing = True if len(self.graph_data["x"]) > 2 else False graph = DataQtGraph( title="ELSA Apparate pro Semester", data=self.graph_data, generateMissing=False, y_label="Anzahl der Apparate", x_rotation=0, ) log.debug(self.graph_data) self.elsa_statistics_table.setRowCount(0) for i in range(len(self.graph_data["x"])): self.elsa_statistics_table.insertRow(0) self.elsa_statistics_table.setItem( 0, 0, QtWidgets.QTableWidgetItem(self.graph_data["x"][i]) ) self.elsa_statistics_table.setItem( 0, 1, QtWidgets.QTableWidgetItem(str(self.graph_data["y"][i])) ) self.elsa_statistics.addTab(graph, "Graph") def launch(): log.debug("Launching Elsa Dialog") app = QtWidgets.QApplication([]) window = ElsaDialog() window.show() app.exec()