diff --git a/src/backend/database.py b/src/backend/database.py index 5efcc6f..35028f4 100644 --- a/src/backend/database.py +++ b/src/backend/database.py @@ -114,7 +114,7 @@ class Database: result = self.query_db("SELECT bookdata, id FROM media WHERE app_id=? AND prof_id=?", (app_id,prof_id)) books = [(load_pickle(i[0]),i[1]) for i in result] # ic(books) - book = [i for i in books if i[0].signature == signature][0] + book = [i for i in books if i[0].signature == signature][0][1] return book def getBookBasedOnSignature(self, app_id:str, prof_id:str,signature:str)->BookData: result = self.query_db("SELECT bookdata FROM media WHERE app_id=? AND prof_id=?", (app_id,prof_id)) @@ -179,7 +179,6 @@ class Database: qdata = self.query_db(f"SELECT id,bookdata,available FROM media WHERE (app_id={app_id} AND prof_id={prof_id}) AND (deleted={deleted if deleted == 0 else '1 OR deleted=0'})") ret_result = [] for result_a in qdata: - ic(result_a) data = {"id": int, "bookdata": BookData, "available": int} data["id"] = result_a[0] data["bookdata"] = pickle.loads(result_a[1]) diff --git a/src/logic/threads.py b/src/logic/threads.py index e3ffd9a..2a935e5 100644 --- a/src/logic/threads.py +++ b/src/logic/threads.py @@ -12,9 +12,10 @@ from icecream import ic class BookGrabber(QThread): updateSignal = pyqtSignal(int, int) - + done = pyqtSignal() def __init__(self,app_id, prof_id, mode, data, parent=None): super(BookGrabber, self).__init__(parent = None) + self.is_Running = True self.logger = MyLogger("Worker") self.logger.log_info("Starting worker thread") self.data = data @@ -36,71 +37,71 @@ class BookGrabber(QThread): # self.book_id = None def run(self): - self.db = Database() - item = 0 - iterdata = self.data - print(iterdata) - for entry in iterdata: - signature = str(entry) - self.logger.log_info("Processing entry: " + signature) + while self.is_Running: + self.db = Database() + item = 0 + iterdata = self.data + print(iterdata) + for entry in iterdata: + signature = str(entry) + self.logger.log_info("Processing entry: " + signature) - webdata = WebRequest().get_ppn(entry).get_data() - if webdata == "error": - continue - bd = BibTextTransformer(self.mode).get_data(webdata).return_data() - transformer = BibTextTransformer("RDS") - rds = transformer.get_data(webdata).return_data("rds_availability") - bd.signature = entry - # confirm lock is acquired - print("lock acquired, adding book to database") - self.db.addBookToDatabase(bd, self.app_id, self.prof_id) - # get latest book id - self.book_id = self.db.getLastBookId() - self.logger.log_info("Added book to database") - state = 0 - print(len(rds.items)) - for rds_item in rds.items: - sign = rds_item.superlocation - loc = rds_item.location - # print(item.location) - if self.app_id in sign or self.app_id in loc: - state = 1 - break + webdata = WebRequest().get_ppn(entry).get_data() + if webdata == "error": + continue + bd = BibTextTransformer(self.mode).get_data(webdata).return_data() + transformer = BibTextTransformer("RDS") + rds = transformer.get_data(webdata).return_data("rds_availability") + bd.signature = entry + # confirm lock is acquired + print("lock acquired, adding book to database") + self.db.addBookToDatabase(bd, self.app_id, self.prof_id) + # get latest book id + self.book_id = self.db.getLastBookId() + self.logger.log_info("Added book to database") + state = 0 + print(len(rds.items)) + for rds_item in rds.items: + sign = rds_item.superlocation + loc = rds_item.location + ic(sign,loc) + ic(rds_item) + if self.app_id in sign or self.app_id in loc: + state = 1 + break - # for book in self.books: - # if book["bookdata"].signature == entry: - # book_id = book["id"] - # break - self.logger.log_info(f"State of {signature}: {state}") - print( - "lock acquired, updating availability of " - + str(self.book_id) - + " to " - + str(state) - ) - try: - self.db.setAvailability(self.book_id, state) - except sqlite3.OperationalError as e: - self.logger.log_error(f"Failed to update availability: {e}") - - # time.sleep(5) - item += 1 - self.updateSignal.emit(item, len(self.data)) - self.logger.log_info("Worker thread finished") - # teminate thread - self.app_id = None - self.prof_id = None - self.mode = None - self.data = None - - self.quit() + # for book in self.books: + # if book["bookdata"].signature == entry: + # book_id = book["id"] + # break + self.logger.log_info(f"State of {signature}: {state}") + print( + "updating availability of " + + str(self.book_id) + + " to " + + str(state) + ) + try: + self.db.setAvailability(self.book_id, state) + except sqlite3.OperationalError as e: + self.logger.log_error(f"Failed to update availability: {e}") + # time.sleep(5) + item += 1 + self.updateSignal.emit(item, len(self.data)) + self.logger.log_info("Worker thread finished") + # self.done.emit() + if not self.is_Running: + break + def stop(self): + self.is_Running = False + class AvailChecker(QThread): updateSignal = pyqtSignal(str, int) updateProgress = pyqtSignal(int,int) def __init__( - self, links: list = [], appnumber: int = None, parent=None, books=list[dict] + self, links: list = None, appnumber: int = None, parent=None, books=list[dict] ): if links is None: links = [] diff --git a/src/logic/userInterface.py b/src/logic/userInterface.py index 5f4a75a..b22ac46 100644 --- a/src/logic/userInterface.py +++ b/src/logic/userInterface.py @@ -174,7 +174,6 @@ class Ui(Ui_Semesterapparat): # self.tableWidget_apparate.text self.actionEinstellungen.triggered.connect(self.open_settings) # set validators - self.sem_year.setValidator(QtGui.QIntValidator()) self.sem_year.setText(str(QtCore.QDate.currentDate().year())) self.prof_mail.setValidator( QRegularExpressionValidator( @@ -306,7 +305,6 @@ class Ui(Ui_Semesterapparat): self.pushButton.clicked.connect(self.delete_user) self.update_user.clicked.connect(self.update_user_data) self.update_faculty_member.clicked.connect(self.edit_faculty_member_action) - def populate_appfach_dropdown(self): self.app_fach.clear() self.app_fach.addItem("") @@ -1100,7 +1098,6 @@ class Ui(Ui_Semesterapparat): text = f"Medium {curr}/{total}" self.logger.log_info(text) self.progress_label.setText(text) - self.MainWindow.setStatusTip(f"Medien werden hinzugefügt, bitte warten... {curr}/{total}") # update tableWidget_apparat_media self.update_app_media_list() @@ -1141,23 +1138,21 @@ class Ui(Ui_Semesterapparat): # create apparat self.btn_save_apparat() # create a thread that updates the progress label after each medium - thread = QThread() grabber = BookGrabber(mode=mode, app_id=app_id, prof_id=prof_id, data=data) # grabber.mode = mode # grabber.data = data # grabber.app_id = app_id # grabber.prof_id = prof_id - grabber.moveToThread(thread) - grabber.finished.connect(thread.quit) grabber.finished.connect(grabber.deleteLater) grabber.finished.connect(self.hide_progress_label) grabber.finished.connect(self.update_app_media_list) grabber.updateSignal.connect(self.update_progress_label) - # worker.finished.connect(worker.deleteLater) grabber.start() - self.threadeds.append(thread) - self.grabbers.append(grabber) + # run grabber.deletelater + grabber.stop() + grabber.wait() + grabber.quit() # for book in data: # # self.progress_label.setText(f"Medium {ct}/{len(data)}") @@ -1177,7 +1172,6 @@ class Ui(Ui_Semesterapparat): self.threadeds.clear() def _update_progress(current, all_titles): self.avail_status.setText( "{}/{}".format(current, all_titles)) - self.btn_reserve.setStatusTip(f"Verfügbarkeit wird geprüft, bitte warten... {current}/{all_titles}") def _hide_progress_label(): self.label_20.hide() self.avail_status.hide() @@ -1208,18 +1202,20 @@ class Ui(Ui_Semesterapparat): deleted=0, ) - thread = QThread() + # thread = QThread() appnumber = self.active_apparat() print(links) availcheck = AvailChecker(links, appnumber, books=books) - availcheck.moveToThread(thread) - availcheck.finished.connect(thread.quit) + # availcheck.moveToThread(thread) + # availcheck.finished.connect(thread.quit) availcheck.finished.connect(availcheck.deleteLater) availcheck.finished.connect(self.update_app_media_list) availcheck.updateProgress.connect(_update_progress) availcheck.finished.connect(_hide_progress_label) availcheck.start() - self.threadeds.append(thread) + # kill availcheck after completion + + # self.threadeds.append(thread) self.grabbers.append(availcheck) def btn_cancel_active_selection(self): @@ -1533,17 +1529,16 @@ class Ui(Ui_Semesterapparat): signatures = [i for i in signatures if i != ""] ic(signatures) print("starting thread") - thread = QThread() grabber = BookGrabber(mode = "ARRAY", app_id = app_id,prof_id = prof_id,data = signatures) # grabber.mode = "ARRAY" # grabber.data = signatures # grabber.app_id = app_id # grabber.prof_id = prof_id - grabber.moveToThread(thread) + # grabber.moveToThread(thread) self.label_info.show() self.progress_label.show() self.line_2.show() - grabber.finished.connect(thread.quit) + # grabber.finished.connect(thread.quit) grabber.finished.connect(grabber.deleteLater) grabber.finished.connect(self.hide_progress_label) grabber.finished.connect(self.update_app_media_list) @@ -1553,6 +1548,7 @@ class Ui(Ui_Semesterapparat): grabber.start() # self.thread = thread + # kill grabber after completion self.grabbers.append(grabber) def unlock_apparate(self): @@ -1818,7 +1814,7 @@ class Ui(Ui_Semesterapparat): signature=book, prof_id=self.db.getProfId(self.drpdwn_prof_name.currentText()), ) - + book_id = self.db.getBookIdBasedOnSignature(self.active_apparat(),self.db.getProfId(self.drpdwn_prof_name.currentText()),book) widget = QtWidgets.QDialog() bookedit = edit_bookdata_ui() bookedit.setupUi(widget) @@ -1841,28 +1837,48 @@ class Ui(Ui_Semesterapparat): selected_apparat_id = self.tableWidget_apparate.item( self.tableWidget_apparate.currentRow(), 0 ).text() - signature = self.tableWidget_apparat_media.item( - self.tableWidget_apparat_media.currentRow(), 1 - ).text() - # bookdata= self.db.getBookIdBasedOnSignature(selected_apparat_id,prof_id=self.db.get_prof_id(self.drpdwn_prof_name.currentText()),signature=signature) - book_id = self.db.getBookIdBasedOnSignature( - selected_apparat_id, - prof_id=self.db.getProfId(self.drpdwn_prof_name.currentText()), - signature=signature, - ) - 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) - print(state) - if state == 1: - self.db.deleteBook(book_id) - self.update_app_media_list() - pass - + # check how many rows are selected + selected_rows = self.tableWidget_apparat_media.selectionModel().selectedRows() + if len(selected_rows) == 1: + signature = self.tableWidget_apparat_media.item( + self.tableWidget_apparat_media.currentRow(), 1 + ).text() + book_id = self.db.getBookIdBasedOnSignature( + selected_apparat_id, + prof_id=self.db.getProfId(self.drpdwn_prof_name.currentText()), + signature=signature, + ) + 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) + print(state) + if state == 1: + self.db.deleteBook(book_id) + self.update_app_media_list() + pass + else: + # get all selected rows + ranges = self.tableWidget_apparat_media.selectedRanges() + rows = [] + for r in ranges: + for row in range(r.topRow(), r.bottomRow() + 1): + rows.append(row) + print(rows) + message = f"Sollen die {len(rows)} Medien wirklich gelöscht werden?" + state = self.confirm_popup(message) + if state == 1: + for _ in rows: + signature = self.tableWidget_apparat_media.item(_, 1).text() + book_id = self.db.getBookIdBasedOnSignature( + selected_apparat_id, + prof_id=self.db.getProfId(self.drpdwn_prof_name.currentText()), + signature=signature, + ) + self.db.deleteBook(book_id) + self.update_app_media_list() def extend_apparat(self): framework = QtWidgets.QDialog() frame = App_Ext_Dialog() frame.setupUi(framework) - frame.sem_year.setValidator(QtGui.QIntValidator()) frame.sem_year.setText(str(QtCore.QDate.currentDate().year())) framework.exec() # return data from dialog if ok is pressed diff --git a/src/ui/Ui_semesterapparat_ui.py b/src/ui/Ui_semesterapparat_ui.py index c74ab85..3a56465 100644 --- a/src/ui/Ui_semesterapparat_ui.py +++ b/src/ui/Ui_semesterapparat_ui.py @@ -23,6 +23,7 @@ class Ui_MainWindow(object): MainWindow.setMinimumSize(QtCore.QSize(1278, 800)) MainWindow.setMaximumSize(QtCore.QSize(1920, 800)) MainWindow.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + MainWindow.setStatusTip("") self.centralwidget = QtWidgets.QWidget(MainWindow) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -1227,7 +1228,7 @@ class Ui_MainWindow(object): self.retranslateUi(MainWindow) self.tabWidget.setCurrentIndex(0) - self.tabWidget_2.setCurrentIndex(0) + self.tabWidget_2.setCurrentIndex(1) self.stackedWidget_4.setCurrentIndex(1) self.tabWidget_3.setCurrentIndex(1) QtCore.QMetaObject.connectSlotsByName(MainWindow) @@ -1320,6 +1321,7 @@ class Ui_MainWindow(object): self.label_6.setText(_translate("MainWindow", "Semester")) self.sem_year.setPlaceholderText(_translate("MainWindow", "2023")) self.label_2.setText(_translate("MainWindow", "Apparatsnummer")) + self.btn_apparat_save.setStatusTip(_translate("MainWindow", "searching")) self.btn_apparat_save.setText(_translate("MainWindow", "Speichern")) self.btn_apparat_apply.setText(_translate("MainWindow", "Aktualisieren")) self.check_eternal_app.setText(_translate("MainWindow", "Dauerapparat")) @@ -1350,7 +1352,8 @@ class Ui_MainWindow(object): item = self.tableWidget_apparat_media.horizontalHeaderItem(3) item.setText(_translate("MainWindow", "Autor")) item = self.tableWidget_apparat_media.horizontalHeaderItem(4) - item.setText(_translate("MainWindow", "verfügbar?")) + 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) diff --git a/src/ui/semesterapparat_ui.ui b/src/ui/semesterapparat_ui.ui index 3ded8b1..c4ba01e 100644 --- a/src/ui/semesterapparat_ui.ui +++ b/src/ui/semesterapparat_ui.ui @@ -40,6 +40,9 @@ Semesterapparatsmanagement + + + @@ -607,6 +610,9 @@ false + + searching + Speichern @@ -1228,7 +1234,10 @@ - verfügbar? + im Apparat? + + + Diese Angabe ist nicht zuverlässig. Ist das ❌ vorhanden, kann das Medium im Apparat sein, aber aufgrund eines Bugs nicht gefunden worden @@ -1427,7 +1436,7 @@ - 0 + 1