From 2836be7490b706be31acb650e3d9a00e07695d6f Mon Sep 17 00:00:00 2001 From: WorldTeacher <41587052+WorldTeacher@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:28:12 +0200 Subject: [PATCH] add updates --- config/config.py | 1 - src/__init__.py | 19 ++--- src/logic/database.py | 34 +++++--- src/logic/documentation_thread.py | 5 +- src/ui/main_ui.py | 127 +++++++++++++++++++++++++++--- src/ui/multiUserInfo.py | 4 +- 6 files changed, 149 insertions(+), 41 deletions(-) diff --git a/config/config.py b/config/config.py index 59133e3..d6b37a7 100644 --- a/config/config.py +++ b/config/config.py @@ -1,7 +1,6 @@ from typing import Optional import omegaconf - class Config: _config: Optional[omegaconf.DictConfig] = None diff --git a/src/__init__.py b/src/__init__.py index 89fbd17..3fed036 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,18 +1,12 @@ -# import argparse - - import sys from config import Config# -import argparse +__version__ = "0.1.0" +__author__ = "Alexander Kirchner" +__email__ = "alexander.kirchner@ph-freiburg.de" +__license__ = "MIT" + config = Config("config/settings.yaml") -__version__ = "0.1.0" -# if programm launched with argument --debug, set debug to True -# if "--debug" in sys.argv: -# config.debug = True -# # if programm launched with argument --log, set log_debug -# if "--log" in sys.argv: -# config.log_debug = True valid_args = ["--debug", "--log", "--no-backup", "--ic-logging", "--version", "-h"] args_description = { @@ -27,7 +21,8 @@ args_description = { args = sys.argv[1:] if any(arg not in valid_args for arg in args): print("Invalid argument present") - sys.exit() + #sys.exit() + def help(): print("Ausleihsystem") print("Ein Ausleihsystem für Handbibliotheken") diff --git a/src/logic/database.py b/src/logic/database.py index 2593398..16beeaa 100644 --- a/src/logic/database.py +++ b/src/logic/database.py @@ -168,7 +168,9 @@ class Database: conn = self.connect() cursor = conn.cursor() cursor.execute(query) - + result = cursor.fetchall() + self.close_connection(conn) + return result def checkUserExists(self, key, value) -> list[User] | bool: query = f"SELECT * FROM users WHERE {key} like '%{value}%'" conn = self.connect() @@ -208,19 +210,28 @@ class Database: return user def getUser(self, user_id) -> User: + conn = self.connect() cursor = conn.cursor() cursor.execute(f"SELECT * FROM users") result = cursor.fetchall() self.close_connection(conn) - - for res in result: - if res[1] == user_id: - user = User(userid=res[1], username=res[2], email=res[3], id=res[0]) - dbg(f"Returning User {user}") - log.info(f"Returning User {user}") - return user - return User(userid="gelöscht", username="gelöscht", email="gelöscht", id="gelöscht") + if len(str(user_id)) == 1: + for res in result: + if res[0] == user_id: + user = User(userid=res[1], username=res[2], email=res[3], id=res[0]) + dbg(f"Returning User {user}") + log.info(f"Returning User {user}") + return user + else: + for res in result: + if res[1] == user_id: + user = User(userid=res[1], username=res[2], email=res[3], id=res[0]) + dbg(f"Returning User {user}") + log.info(f"Returning User {user}") + return user + raise ValueError(f"User {user_id} not found") + #return User(userid="gelöscht", username="gelöscht", email="gelöscht", id="gelöscht") # user = User(userid=result[1], username=result[2], email=result[3],id = result[0]) # return user @@ -287,6 +298,11 @@ class Database: log.info(f"Returning Active Loans {result}") return str(len(result)) + def getMediaList(self): + query = "SELECT signature FROM media" + result = self.query(query) + + return [res[0] for res in result] def getAllLoans(self): loan_data = [] query = "SELECT * FROM loans" diff --git a/src/logic/documentation_thread.py b/src/logic/documentation_thread.py index ed2c7cc..0ebd344 100644 --- a/src/logic/documentation_thread.py +++ b/src/logic/documentation_thread.py @@ -6,7 +6,4 @@ class DocumentationThread(QThread): super().__init__() def run(self): - launch_documentation() - - - + launch_documentation() \ No newline at end of file diff --git a/src/ui/main_ui.py b/src/ui/main_ui.py index cbdbffd..e6f533d 100644 --- a/src/ui/main_ui.py +++ b/src/ui/main_ui.py @@ -1,7 +1,9 @@ +import os import sys import atexit import datetime -from src import config +import webbrowser +from src import config, __email__ from src.logic import Database, Catalogue, Backup from src.utils import stringToDate, Icon, Log from src.utils import debugMessage as dbg @@ -16,14 +18,18 @@ from .settings import Settings from .newBook import NewBook from .loans import LoanWindow from .reportUi import ReportUi - -from PyQt6 import QtCore, QtWidgets - +from src.utils import launch_documentation +from PyQt6 import QtCore, QtWidgets, QtGui +from omegaconf import OmegaConf +from src.logic.documentation_thread import DocumentationThread backup = Backup() cat = Catalogue() log = Log("main") dbg(backup=config.database.do_backup, catalogue=config.catalogue) +def getShortcut(shortcuts, name): + shortcut = [cut for cut in shortcuts if cut["name"] == name][0] + return shortcut["current"] class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): @@ -38,13 +44,21 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): self.actionRueckgabemodus.triggered.connect(self.changeMode) self.actionNutzer.triggered.connect(self.showUser) self.actionEinstellungen.triggered.connect(self.showSettings) - self.actionAusleihistorie.triggered.connect(self.showLoanHistory) + self.actionAusleihhistorie.triggered.connect(self.showLoanHistory) self.actionBericht_erstellen.triggered.connect(self.generateReport) + self.actionDokumentation_ffnen.triggered.connect(self.openDocumentation) + self.actionBeenden.triggered.connect(self.shutdown) + def __mail(): + webbrowser.open(f"mailto:{__email__}") + self.actionProblem_melden.triggered.connect(__mail) + #if close button is pressed call shutdown + self.closeEvent = self.shutdown # Buttons self.btn_show_lentmedia.clicked.connect(self.showUser) self.btn_createNewUser.clicked.connect(self.createUser) self.btn_createNewUser.setText("") self.btn_createNewUser.setIcon(Icon("add_user").overwriteColor("#1E90FF")) + self.mode.clicked.connect(self.changeMode) # LineEdits self.input_userno.returnPressed.connect( @@ -67,13 +81,15 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): QtWidgets.QHeaderView.ResizeMode.Stretch ) self.input_file_ident.setFocus() - # self.userdata.textChanged.connect(lambda: self.mode.setText("Ausleihe")) + self.assignShortcuts() # variables self.db = Database() self.currentDate = QtCore.QDate.currentDate() loanDate = self.currentDate.addDays(config.loan_duration) self.activeUser = None self.activeState = "Rückgabe" + self.docu = DocumentationThread() + # self.docu.start() self.duedate.setDate(loanDate) # functions @@ -84,6 +100,24 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): else: log.warning("Backup disabled") self.show() + + def shutdown(self, *args): + #kill documentation thread + log.info("Shutting down") + self.docu.terminate() + sys.exit() + + + def assignShortcuts(self): + shortcuts = config.shortcuts + shortcuts = OmegaConf.to_container(shortcuts) + #convert to dictconfig + + self.actionDokumentation_ffnen.setShortcut(getShortcut(shortcuts, "Hilfe")) + self.actionAusleihhistorie.setShortcut(getShortcut(shortcuts, "Ausleihhistorie")) + self.actionBericht_erstellen.setShortcut(getShortcut(shortcuts, "Bericht_erstellen")) + self.actionNutzer.setShortcut(getShortcut(shortcuts, "Nutzer")) + self.actionRueckgabemodus.setShortcut(getShortcut(shortcuts, "Rueckgabemodus")) def generateReport(self): log.info("Generating Report") @@ -106,15 +140,53 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): log.info("Showing Settings") settings = Settings() settings.exec() + result = settings.result() + if result == 1: + #dialog to ask if program should be restarted + dialog = QtWidgets.QMessageBox() + dialog.setWindowTitle("Einstellungen geändert") + dialog.setIcon(QtWidgets.QMessageBox.Icon.Information) + dialog.setText("Einstellungen wurden geändert\nProgramm neu starten?") + dialog.setStandardButtons( + QtWidgets.QMessageBox.StandardButton.Yes + | QtWidgets.QMessageBox.StandardButton.No + ) + dialog.setDefaultButton(QtWidgets.QMessageBox.StandardButton.No) + #translate buttons + yes = dialog.button(QtWidgets.QMessageBox.StandardButton.Yes) + yes.setText("Ja") + no = dialog.button(QtWidgets.QMessageBox.StandardButton.No) + no.setText("Nein") + dialog.exec() + result = dialog.result() + if result == QtWidgets.QMessageBox.StandardButton.Yes: + self.restart() # reload settings #print(config) + def openDocumentation(self): + log.info("Opening Documentation") + webbrowser.open("http://localhost:6543") + + + + + def restart(self): + #log restart + dbg("Restarting Program") + import os + python_executable = sys.executable + args = sys.argv[:] + args.insert(0, sys.executable) + os.execvp(python_executable, args) + + def changeMode(self): log.info("Changing Mode") dbg(f"Current mode: {self.activeState}") self.input_username.clear() stayReturn = False - if self.userdata.toPlainText() != "": + if config.advanced_refresh and self.userdata.toPlainText() != "": stayReturn = True self.userdata.clear() self.input_userno.clear() @@ -138,9 +210,10 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): self.input_username.setEnabled(True) self.input_userno.setEnabled(True) self.duedate.setEnabled(True) + self.input_username.setPlaceholderText("") + self.input_userno.setPlaceholderText("") self.input_userno.setFocus() # set mode background color to blue with rounded edges - # self.mode.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.mode.setStyleSheet("background-color: #1E90FF") self.mode.setText("Ausleihe") self.activeState = "Ausleihe" @@ -161,6 +234,8 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): self.mode.setText("Rückgabe") self.input_file_ident.setEnabled(True) self.input_file_ident.setPlaceholderText("Buchidentifikation eingeben") + self.input_username.setPlaceholderText("Bitte erst in den Ausleihmodus wechseln") + self.input_userno.setPlaceholderText("Bitte erst in den Ausleihmodus wechseln") def showUser(self): log.info(f"Showing User {self.activeUser}") @@ -180,7 +255,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): ) # self.user_ui.setFields("John Doe", "123456789", "test@mail.com") self.user_ui.show() - + def setUserData(self): log.info("Setting User Data") self.input_username.setText(str(self.activeUser.username)) @@ -188,7 +263,6 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): self.userdata.setText(self.activeUser.__repr__()) today = QtCore.QDate.currentDate().toString("yyyy-MM-dd") self.db.setUserActiveDate(self.activeUser.userid, today) - # self.mode.setText("Ausleihe") def createUser(self): log.info("Creating User") @@ -260,7 +334,20 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): value = self.input_file_ident.text().strip() log.debug(f"Handling Line Input {value}") if self.mode.text() == "Rückgabe": - self.returnMedia(value) + if value in self.db.getMediaList(): + self.returnMedia(value) + else: + # create warning dialog + log.info("Invalid Input") + dialog = QtWidgets.QMessageBox() + dialog.setWindowTitle("Ungültige Eingabe") + dialog.setIcon(QtWidgets.QMessageBox.Icon.Warning) + dialog.setWindowIcon(Icon("warning").overwriteColor("#EA3323")) + dialog.setText("Eingabe ist nicht in der Datenbank\nBitte prüfen und erneut eingeben") + dialog.exec() + self.input_file_ident.setFocus() + self.input_file_ident.clear() + return else: if not " " in value: # create warning dialog @@ -294,7 +381,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): self.input_file_ident.setEnabled(True) return book_id = self.db.insertMedia(media) - self.loanMedia(user_id, [book_id], media) + self.loanMedia(user_id, [book_id]) else: newbook = NewBook() newbook.exec() @@ -410,6 +497,8 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): dbg("Book not found") #print("Book not found") #self.input_file_ident.setPlaceholderText(f"Buch {identifier} nicht gefunden") + + def setStatusTipMessage(self, message): dialog = QtWidgets.QMessageBox() @@ -460,9 +549,21 @@ def launch(*argv): options = [arg for arg in options if arg.startswith("--")] #print("Launching Main UI") #print(options) - + QtCore.QLocale().setDefault(QtCore.QLocale(QtCore.QLocale.Language.German, QtCore.QLocale.Country.Germany)) + SYSTEM_LANGUAGE = QtCore.QLocale().system().name() + print(SYSTEM_LANGUAGE) + + # Load base QT translations from the normal place app = QtWidgets.QApplication([]) main_ui = MainUI() + #translate ui to system language + if SYSTEM_LANGUAGE: + translator = QtCore.QTranslator() + #do not use ascii encoding + translator.load(f"qt_{SYSTEM_LANGUAGE}", "translations") + translator.load("app.qm", "translations") + app.installTranslator(translator) + atexit.register(exit_handler) sys.exit(app.exec()) # sys.exit(app.exec()) diff --git a/src/ui/multiUserInfo.py b/src/ui/multiUserInfo.py index 6a4ede0..8f8c88c 100644 --- a/src/ui/multiUserInfo.py +++ b/src/ui/multiUserInfo.py @@ -29,7 +29,7 @@ class MultiUserFound(QtWidgets.QDialog, Ui_Dialog): def selectUser(self, row, column): #print(row, column) user = User( - id=self.tableWidget.item(row, 0).text(), + userid=self.tableWidget.item(row, 0).text(), username=self.tableWidget.item(row, 1).text(), email=self.tableWidget.item(row, 2).text(), ) @@ -39,6 +39,6 @@ class MultiUserFound(QtWidgets.QDialog, Ui_Dialog): def displayUsers(self): for user in self.users: self.tableWidget.insertRow(0) - self.tableWidget.setItem(0, 0, QtWidgets.QTableWidgetItem(str(user.id))) + self.tableWidget.setItem(0, 0, QtWidgets.QTableWidgetItem(str(user.userid))) self.tableWidget.setItem(0, 1, QtWidgets.QTableWidgetItem(user.username)) self.tableWidget.setItem(0, 2, QtWidgets.QTableWidgetItem(user.email))