Refactor user interface: enhance sound playback functionality and integrate signature update process,
fix broken database calls by using the app_id instead of the previously used appnr
This commit is contained in:
@@ -7,14 +7,14 @@ import time
|
||||
import webbrowser
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any, Union
|
||||
from typing import Any, List, Optional, Tuple, Union
|
||||
|
||||
import loguru
|
||||
from natsort import natsorted
|
||||
from PySide6 import QtCore, QtGui, QtWidgets
|
||||
from PySide6.QtMultimedia import QAudioOutput, QMediaPlayer
|
||||
from PySide6.QtCore import QThread
|
||||
from PySide6.QtGui import QRegularExpressionValidator
|
||||
from PySide6.QtMultimedia import QAudioOutput, QMediaPlayer
|
||||
|
||||
from src import LOG_DIR, Icon
|
||||
from src.backend import (
|
||||
@@ -59,7 +59,10 @@ from src.ui.widgets import (
|
||||
FilePicker,
|
||||
MessageCalendar,
|
||||
NewEditionChecker,
|
||||
NewEditionCheckSelector,
|
||||
SearchStatisticPage,
|
||||
UpdaterThread,
|
||||
UpdateSignatures,
|
||||
UserCreate,
|
||||
)
|
||||
|
||||
@@ -76,13 +79,6 @@ log.add(
|
||||
log.success("UI started")
|
||||
valid_input = (0, 0, 0, 0, 0, 0)
|
||||
|
||||
def play_sound(sound_file:str):
|
||||
player = QMediaPlayer()
|
||||
audio_output = QAudioOutput()
|
||||
player.setAudioOutput(audio_output)
|
||||
player.setSource(f"sounds/{sound_file}")
|
||||
player.play()
|
||||
|
||||
|
||||
class Ui(Ui_Semesterapparat):
|
||||
# use the Ui_MainWindow class from mainwindow.py
|
||||
@@ -256,6 +252,7 @@ class Ui(Ui_Semesterapparat):
|
||||
self.availChecker = None
|
||||
self.mail_thread = None
|
||||
self.autoGrabber = None
|
||||
self.newEditionChecker = NewEditionCheckerThread()
|
||||
|
||||
self.elsatab.setLayout(QtWidgets.QVBoxLayout())
|
||||
self.search_statistics.setLayout(QtWidgets.QVBoxLayout())
|
||||
@@ -270,6 +267,9 @@ class Ui(Ui_Semesterapparat):
|
||||
|
||||
self.steps.hide()
|
||||
|
||||
self.player = QMediaPlayer()
|
||||
self.audio_output = QAudioOutput()
|
||||
|
||||
self.valid_check_semester.clicked.connect(self.display_valid_semester) # type:ignore
|
||||
|
||||
def create_doc(self):
|
||||
@@ -313,6 +313,9 @@ class Ui(Ui_Semesterapparat):
|
||||
elif self.select_action_box.currentText() == "Lehrperson bearbeiten":
|
||||
self.setWidget(EditProf())
|
||||
self.admin_action.setTitle("Lehrperson bearbeiten")
|
||||
elif self.select_action_box.currentText() == "Signaturen aktualisieren":
|
||||
self.setWidget(UpdateSignatures())
|
||||
self.admin_action.setTitle("Signaturen aktualisieren")
|
||||
else:
|
||||
self.hideWidget()
|
||||
self.admin_action.setTitle("")
|
||||
@@ -330,6 +333,12 @@ class Ui(Ui_Semesterapparat):
|
||||
tempdelete()
|
||||
sys.exit()
|
||||
|
||||
def play_sound(self, sound_file: str):
|
||||
self.player.setAudioOutput(self.audio_output)
|
||||
self.audio_output.setVolume(50)
|
||||
self.player.setSource(QtCore.QUrl.fromLocalFile(f"src/sounds/{sound_file}"))
|
||||
self.player.play()
|
||||
|
||||
def get_apparats(self):
|
||||
alist = self.db.getAllAparats(deleted=0)
|
||||
alist = natsorted(alist, key=lambda x: x.appnr, reverse=True)
|
||||
@@ -417,7 +426,7 @@ class Ui(Ui_Semesterapparat):
|
||||
else:
|
||||
return f"WiSe {currentYear}/{currentYear + 1}"
|
||||
|
||||
def open_apparat(self, apparat):
|
||||
def open_apparat(self, apparat: Union[int, str]):
|
||||
if self.load_app_data(apparat):
|
||||
# change tab focus to tab 0
|
||||
self.tabWidget.setCurrentIndex(0)
|
||||
@@ -626,17 +635,17 @@ class Ui(Ui_Semesterapparat):
|
||||
self.prof_mail.setText(data.mail)
|
||||
self.app_name.setFocus()
|
||||
|
||||
def get_index_of_value(self, table_widget, value):
|
||||
def get_index_of_value(self, table_widget: QtWidgets.QTableWidget, value: str):
|
||||
for i in range(table_widget.rowCount()):
|
||||
for j in range(table_widget.columnCount()):
|
||||
if (
|
||||
table_widget.item(i, j) is not None
|
||||
and table_widget.item(i, j).text() == value
|
||||
and table_widget.item(i, j).text() == value # type: ignore
|
||||
):
|
||||
return i, j
|
||||
return (None, None)
|
||||
|
||||
def load_app_data(self, app_id=None):
|
||||
def load_app_data(self, app_id: Optional[Union[int, str]] = None):
|
||||
self.cancel_active_selection.setEnabled(True)
|
||||
self.add_medium.setEnabled(True)
|
||||
for child in self.app_group_box.findChildren(QtWidgets.QToolButton):
|
||||
@@ -866,8 +875,9 @@ class Ui(Ui_Semesterapparat):
|
||||
|
||||
def update_app_media_list(self):
|
||||
deleted = 0 if not self.chkbx_show_del_media.isChecked() else 1
|
||||
app_id = self.active_apparat
|
||||
app_id = self.db.getId(self.app_name.text())
|
||||
prof_id = self.db.getProfId(self.profdata)
|
||||
print(app_id, prof_id)
|
||||
books: list[dict[int, BookData, int]] = self.db.getBooks(
|
||||
app_id, prof_id, deleted
|
||||
)
|
||||
@@ -1201,6 +1211,7 @@ class Ui(Ui_Semesterapparat):
|
||||
for runner in self.bookGrabber:
|
||||
if not runner.isRunning():
|
||||
runner.deleteLater()
|
||||
self.bookGrabber.remove(runner)
|
||||
# #log.debug("Checking file")
|
||||
# get active app_id and prof_id
|
||||
self.tableWidget_apparate.setEnabled(False)
|
||||
@@ -1497,22 +1508,34 @@ class Ui(Ui_Semesterapparat):
|
||||
self.avail_status.setText("0/0")
|
||||
|
||||
def check_new_editions(self):
|
||||
# create a dialog that asks "Prof oder Apparat" with a button for each. based on that either search through the books of the apparat, or all books associated with the prof
|
||||
selector = NewEditionCheckSelector()
|
||||
selector.exec()
|
||||
pick = selector.selection
|
||||
|
||||
app_id = self.tableWidget_apparate.item(
|
||||
self.tableWidget_apparate.currentRow(), 0
|
||||
).text()
|
||||
prof_id: int = self.db.getProfIDByApparat(app_id)
|
||||
app_name = self.tableWidget_apparate.item(
|
||||
self.tableWidget_apparate.currentRow(), 1
|
||||
).text()
|
||||
subject = self.tableWidget_apparate.item(
|
||||
self.tableWidget_apparate.currentRow(), 4
|
||||
).text()
|
||||
|
||||
prof_id: int = self.db.getProfIDByApparat(app_id)
|
||||
books = self.db.getBooks(app_id, prof_id, deleted=0)
|
||||
if pick == "professor":
|
||||
books = self.db.getBooksByProfId(prof_id)
|
||||
app_name = "Sammelmail"
|
||||
app_id = ", ".join(
|
||||
[str(app.appnr) for app in self.db.getApparatsByProf(prof_id)]
|
||||
)
|
||||
else:
|
||||
books = self.db.getBooks(app_id, prof_id, deleted=0)
|
||||
books = [book["bookdata"] for book in books]
|
||||
log.info(f"Checking {len(books)} for new editions")
|
||||
self.newEditionChecker = NewEditionCheckerThread(books)
|
||||
self.newEditionChecker.finished.connect(self.newEditionChecker.deleteLater)
|
||||
|
||||
self.newEditionChecker.entries = books
|
||||
self.newEditionChecker.finished.connect(self.newEditionChecker.reset)
|
||||
|
||||
self.progressBar.setMaximum(len(books))
|
||||
self.newEditionChecker.updateSignal.connect(self.update_status)
|
||||
@@ -1520,13 +1543,18 @@ class Ui(Ui_Semesterapparat):
|
||||
self.newEditionChecker.start()
|
||||
while self.newEditionChecker.isRunning():
|
||||
QtWidgets.QApplication.processEvents()
|
||||
play_sound("ding.mp3")
|
||||
self.play_sound("ding.mp3")
|
||||
results = self.newEditionChecker.results
|
||||
if results == []:
|
||||
return
|
||||
log.info(f"Found {len(results)} possible new editions - opening dialog")
|
||||
newEditionChecker = NewEditionChecker(results=results)
|
||||
newEditionChecker.exec()
|
||||
|
||||
accepted_books = newEditionChecker.accepted_books
|
||||
# print(accepted_books)
|
||||
if accepted_books == []:
|
||||
return
|
||||
|
||||
self.mail_thread = Mail_Dialog(
|
||||
prof_name=self.db.getSpecificProfData(prof_id, ["fullname"]),
|
||||
@@ -1535,7 +1563,7 @@ class Ui(Ui_Semesterapparat):
|
||||
app_name=app_name,
|
||||
app_subject=subject,
|
||||
accepted_books=accepted_books,
|
||||
default_mail="Neuauflagen für Semesterapparat"
|
||||
default_mail="Neuauflagen für Semesterapparat",
|
||||
)
|
||||
self.mail_thread.show()
|
||||
|
||||
@@ -1625,8 +1653,45 @@ class Ui(Ui_Semesterapparat):
|
||||
menu.exec(self.tableWidget_apparat_media.mapToGlobal(position)) # type: ignore
|
||||
|
||||
def update_data(self):
|
||||
# TODO: use link in table, parse data and if needed, update location / signature
|
||||
pass
|
||||
signatures = [
|
||||
self.tableWidget_apparat_media.item(row, 1).text()
|
||||
for row in range(self.tableWidget_apparat_media.rowCount())
|
||||
] # type: ignore
|
||||
prof_id = self.db.getProfId(self.profdata) # type: ignore
|
||||
app_id = self.active_apparat
|
||||
books: List[Tuple[int, BookData]] = []
|
||||
for signature in signatures:
|
||||
book = self.db.getBookBasedOnSignature(
|
||||
app_id=app_id,
|
||||
signature=signature,
|
||||
prof_id=prof_id,
|
||||
)
|
||||
book_id = self.db.getBookIdBasedOnSignature(
|
||||
self.active_apparat,
|
||||
prof_id,
|
||||
signature,
|
||||
)
|
||||
books.append((book_id, book))
|
||||
# self.autoUpdater.entries = books
|
||||
# self.autoUpdater.finished.connect(self.autoUpdater.reset)
|
||||
self.updater = UpdaterThread()
|
||||
u_books = []
|
||||
for book_id, book in books:
|
||||
u_books.append({"id": book_id, "bookdata": book})
|
||||
self.updater.books = u_books
|
||||
self.progressBar.setMaximum(len(books))
|
||||
self.updater.finished.connect(self.updater.deleteLater)
|
||||
self.updater.finished.connect(self.update_app_media_list)
|
||||
self.updater.currtot.connect(self.update_status)
|
||||
self.updater.start()
|
||||
# ppn = book.link.split("kid=")[-1]
|
||||
# result = cat.get_book(ppn)
|
||||
# if result:
|
||||
# book.signature = result.signature
|
||||
# book.in_apparat = True
|
||||
# print(book)
|
||||
# self.db.updateBookdata(book_id, book)
|
||||
# self.update_app_media_list()
|
||||
|
||||
def copy_to_apparat(self):
|
||||
selected_rows = self.tableWidget_apparat_media.selectionModel().selectedRows() # type: ignore
|
||||
@@ -1724,12 +1789,12 @@ class Ui(Ui_Semesterapparat):
|
||||
).text()
|
||||
prof_id = self.db.getProfId(self.profdata)
|
||||
data = self.db.getBookBasedOnSignature(
|
||||
app_id=self.active_apparat,
|
||||
app_id=self.db.getId(self.app_name.text()),
|
||||
signature=book,
|
||||
prof_id=prof_id,
|
||||
)
|
||||
book_id = self.db.getBookIdBasedOnSignature(
|
||||
self.active_apparat,
|
||||
self.db.getId(self.app_name.text()),
|
||||
prof_id,
|
||||
book,
|
||||
)
|
||||
@@ -1891,7 +1956,13 @@ class Ui(Ui_Semesterapparat):
|
||||
if state == 1:
|
||||
log.debug("Deleting apparat {}", selected_apparat_id)
|
||||
pid = self.db.getProfIDByApparat(selected_apparat_id)
|
||||
self.db.deleteApparat(selected_apparat_id, Semester().value)
|
||||
apparat = Apparat(
|
||||
appnr=int(selected_apparat_id),
|
||||
name=self.tableWidget_apparate.item(
|
||||
self.tableWidget_apparate.currentRow(), 1
|
||||
).text(),
|
||||
)
|
||||
self.db.deleteApparat(apparat=apparat, semester=Semester().value)
|
||||
# delete the corresponding entry from self.apparats
|
||||
for apparat in self.apparats:
|
||||
if apparat.appnr == int(selected_apparat_id):
|
||||
@@ -1935,6 +2006,7 @@ def launch_gui():
|
||||
) # if that thread uses an event loop
|
||||
app.aboutToQuit.connect(aui.docu.terminate) # our new slot
|
||||
app.aboutToQuit.connect(aui.docu.wait)
|
||||
app.aboutToQuit.connect(aui.newEditionChecker.terminate)
|
||||
atexit.register(tempdelete)
|
||||
# atexit.register(aui.validate_thread.quit)
|
||||
# atexit.register(aui.docu.quit)
|
||||
|
||||
Reference in New Issue
Block a user