Files
SemesterapparatsManager/src/ui/widgets/elsa_main.py

501 lines
19 KiB
Python

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()