diff --git a/src/logic/thread_bookgrabber.py b/src/logic/thread_bookgrabber.py new file mode 100644 index 0000000..87c1c19 --- /dev/null +++ b/src/logic/thread_bookgrabber.py @@ -0,0 +1,99 @@ +import sqlite3 +import time + +from icecream import ic +from PySide6.QtCore import QThread, Signal + +from src.backend.database import Database +from src.logic.log import MyLogger +from src.logic.webrequest import BibTextTransformer, WebRequest + +# from src.transformers import RDS_AVAIL_DATA + + +class BookGrabber(QThread): + updateSignal = Signal(int, int) + done = Signal() + + 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 + self.app_id = app_id + self.prof_id = prof_id + self.mode = mode + self.book_id = None + self.state = (self.app_id, self.prof_id, self.mode, self.data) + ic(self.state) + time.sleep(2) + + # def resetValues(self): + # self.app_id = None + # self.prof_id = None + # self.mode = None + # self.data = None + # self.book_id = None + + def run(self): + 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 + 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( + "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() + self.stop() + if not self.is_Running: + break + + def stop(self): + self.is_Running = False diff --git a/src/logic/threads.py b/src/logic/threads.py index 50204f8..387bc79 100644 --- a/src/logic/threads.py +++ b/src/logic/threads.py @@ -1,210 +1,20 @@ +import os import sqlite3 -import threading import time from icecream import ic +from omegaconf import OmegaConf +from PySide6 import QtWidgets from PySide6.QtCore import QThread, Signal from src.backend.database import Database from src.logic.log import MyLogger from src.logic.webrequest import BibTextTransformer, WebRequest -from src.transformers import RDS_AVAIL_DATA +# from src.transformers import RDS_AVAIL_DATA +from src.ui.dialogs.Ui_mail_preview import Ui_eMailPreview -class BookGrabber(QThread): - updateSignal = Signal(int, int) - done = Signal() - - 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 - self.app_id = app_id - self.prof_id = prof_id - self.mode = mode - self.book_id = None - self.state = (self.app_id, self.prof_id, self.mode, self.data) - ic(self.state) - time.sleep(2) - - # def resetValues(self): - # self.app_id = None - # self.prof_id = None - # self.mode = None - # self.data = None - # self.book_id = None - - def run(self): - 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 - 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( - "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() - self.stop() - if not self.is_Running: - break - - def stop(self): - self.is_Running = False - - -class AvailChecker(QThread): - updateSignal = Signal(str, int) - updateProgress = Signal(int, int) - - def __init__( - self, links: list = None, appnumber: int = None, parent=None, books=list[dict] - ): - if links is None: - links = [] - super().__init__(parent) - self.logger = MyLogger("AvailChecker") - self.logger.log_info("Starting worker thread") - self.logger.log_info( - "Checking availability for " - + str(links) - + " with appnumber " - + str(appnumber) - + "..." - ) - self.links = links - self.appnumber = appnumber - self.books = books - self.logger.log_info( - f"Started worker with appnumber: {self.appnumber} and links: {self.links} and {len(self.books)} books..." - ) - time.sleep(2) - - def run(self): - self.db = Database() - state = 0 - count = 0 - for link in self.links: - self.logger.log_info("Processing entry: " + str(link)) - data = WebRequest().get_ppn(link).get_data() - transformer = BibTextTransformer("RDS") - rds = transformer.get_data(data).return_data("rds_availability") - - book_id = None - for item in rds.items: - sign = item.superlocation - loc = item.location - # print(item.location) - if self.appnumber in sign or self.appnumber in loc: - state = 1 - break - for book in self.books: - if book["bookdata"].signature == link: - book_id = book["id"] - break - self.logger.log_info(f"State of {link}: " + str(state)) - print("Updating availability of " + str(book_id) + " to " + str(state)) - self.db.setAvailability(book_id, state) - count += 1 - self.updateProgress.emit(count, len(self.links)) - self.updateSignal.emit(item.callnumber, state) - - self.logger.log_info("Worker thread finished") - # teminate thread - - self.quit() - - -class AutoAdder(QThread): - updateSignal = Signal(int) - - setTextSignal = Signal(int) - progress = Signal(int) - - def __init__(self, data=None, app_id=None, prof_id=None, parent=None): - super().__init__(parent) - self.logger = MyLogger("AutoAdder") - self.data = data - self.app_id = app_id - self.prof_id = prof_id - - print("Launched AutoAdder") - print(self.data, self.app_id, self.prof_id) - - def run(self): - self.db = Database() - # show the dialog, start the thread to gather data and dynamically update progressbar and listwidget - self.logger.log_info("Starting worker thread") - item = 0 - for entry in self.data: - try: - # webdata = WebRequest().get_ppn(entry).get_data() - # bd = BibTextTransformer("ARRAY").get_data(webdata).return_data() - # bd.signature = entry - self.updateSignal.emit(item) - self.setTextSignal.emit(entry) - # qsleep - item += 1 - self.progress.emit(item) - print(item, len(self.data)) - time.sleep(1) - - except Exception as e: - print(e) - self.logger.log_exception( - f"The query failed with message {e} for signature {entry}" - ) - continue - if item == len(self.data): - self.logger.log_info("Worker thread finished") - # teminate thread - self.finished.emit() +config = OmegaConf.load("config.yaml") class BackgroundChecker(QThread): @@ -269,3 +79,135 @@ class MockAvailCheck: self.logger.log_info("Worker thread finished") # teminate thread + + +class Mailer(Ui_eMailPreview): + + updateSignal = Signal(int) + + def __init__(self, data=None, parent=None): + super(QThread).__init__() + super(Ui_eMailPreview).__init__() + + self.logger = MyLogger("Mailer") + self.data = data + self.appid = data["app_id"] + self.appname = data["app_name"] + self.subject = data["app_subject"] + self.profname = data["prof_name"] + self.mail_data = "" + self.prof_mail = data["prof_mail"] + self.dialog = QtWidgets.QDialog() + self.comboBox.currentIndexChanged.connect(self.set_mail) + self.prof_name.setText(self.prof_name) + self.mail_name.setText(self.prof_mail) + self.load_mail_templates() + self.gender_female.clicked.connect(self.set_mail) + self.gender_male.clicked.connect(self.set_mail) + self.gender_non.clicked.connect(self.set_mail) + self.buttonBox.accepted.connect(self.createAndSendMail) + + def load_mail_templates(self): + print("loading mail templates") + mail_templates = os.listdir("mail_vorlagen") + for template in mail_templates: + self.comboBox.addItem(template) + + def get_greeting(self): + if self.gender_male.isChecked(): + return "Sehr geehrter Herr" + elif self.gender_female.isChecked(): + return "Sehr geehrte Frau" + elif self.gender_non.isChecked(): + return "Guten Tag" + + def set_mail(self): + email_template = self.comboBox.currentText() + if email_template == "": + return + with open(f"mail_vorlagen/{email_template}", "r", encoding="utf-8") as f: + mail_template = f.read() + email_header = email_template.split(".eml")[0] + if "{AppNr}" in email_template: + email_header = email_template.split(".eml")[0] + email_header = email_header.format(AppNr=self.appid, AppName=self.appname) + self.mail_header.setText(email_header) + self.mail_data = mail_template.split("")[0] + mail_html = mail_template.split("")[1] + mail_html = "" + mail_html + Appname = self.appname + mail_html = mail_html.format( + Profname=self.prof_name.text().split(" ")[-1], + Appname=Appname, + AppNr=self.appid, + AppSubject=self.subject, + greeting=self.get_greeting(), + ) + + self.mail_body.setHtml(mail_html) + + def createAndSendMail(self): + import smtplib + import ssl + from email.mime.multipart import MIMEMultipart + from email.mime.text import MIMEText + + smtp_server = config["mail"]["smtp_server"] + port: int = config["mail"]["port"] + sender_email = config["mail"]["sender"] + password = config["mail"]["password"] + message = MIMEMultipart() + message["From"] = sender_email + message["To"] = self.prof_mail + message["Subject"] = self.mail_header.text() + mail_body = self.mail_body.toHtml() + message.attach(MIMEText(mail_body, "html")) + mail = message.as_string() + + server = smtplib.SMTP_SSL(smtp_server, port) + # server.starttls() + # server.auth(mechanism="PLAIN") + if config["mail"]["use_user_name"] == 1: + print(config["mail"]["user_name"]) + server.login(config["mail"]["user_name"], password) + else: + server.login(sender_email, password) + server.sendmail(sender_email, self.prof_mail, mail) + print("Mail sent") + # end active process + server.quit() + + +class MailThread(QThread): + + updateSignal = Signal(int) + + def __init__(self, data=None, parent=None): + super(QThread).__init__() + super(MailThread).__init__() + self.logger = MyLogger("MailThread") + self.data = data + + def show_ui(self): + self.mailer = Mailer() + self.mailer.__init__() + self.mailer.dialog.exec_() + self.mailer.dialog.show() + + def run(self): + self.show_ui() + self.updateSignal.emit(1) + + + + + + + + + + + + + + diff --git a/src/logic/threads_autoadder.py b/src/logic/threads_autoadder.py new file mode 100644 index 0000000..9419f69 --- /dev/null +++ b/src/logic/threads_autoadder.py @@ -0,0 +1,55 @@ +import time + +from icecream import ic +from PySide6.QtCore import QThread, Signal + +from src.backend.database import Database +from src.logic.log import MyLogger + +# from src.transformers import RDS_AVAIL_DATA + + +class AutoAdder(QThread): + updateSignal = Signal(int) + + setTextSignal = Signal(int) + progress = Signal(int) + + def __init__(self, data=None, app_id=None, prof_id=None, parent=None): + super().__init__(parent) + self.logger = MyLogger("AutoAdder") + self.data = data + self.app_id = app_id + self.prof_id = prof_id + + print("Launched AutoAdder") + print(self.data, self.app_id, self.prof_id) + + def run(self): + self.db = Database() + # show the dialog, start the thread to gather data and dynamically update progressbar and listwidget + self.logger.log_info("Starting worker thread") + item = 0 + for entry in self.data: + try: + # webdata = WebRequest().get_ppn(entry).get_data() + # bd = BibTextTransformer("ARRAY").get_data(webdata).return_data() + # bd.signature = entry + self.updateSignal.emit(item) + self.setTextSignal.emit(entry) + # qsleep + item += 1 + self.progress.emit(item) + print(item, len(self.data)) + time.sleep(1) + + except Exception as e: + print(e) + self.logger.log_exception( + f"The query failed with message {e} for signature {entry}" + ) + continue + if item == len(self.data): + self.logger.log_info("Worker thread finished") + # teminate thread + self.finished.emit() diff --git a/src/logic/threads_availchecker.py b/src/logic/threads_availchecker.py new file mode 100644 index 0000000..2bce576 --- /dev/null +++ b/src/logic/threads_availchecker.py @@ -0,0 +1,72 @@ +import time + +from icecream import ic +from PySide6.QtCore import QThread, Signal + +from src.backend.database import Database +from src.logic.log import MyLogger +from src.logic.webrequest import BibTextTransformer, WebRequest + +# from src.transformers import RDS_AVAIL_DATA + + +class AvailChecker(QThread): + updateSignal = Signal(str, int) + updateProgress = Signal(int, int) + + def __init__( + self, links: list = None, appnumber: int = None, parent=None, books=list[dict] + ): + if links is None: + links = [] + super().__init__(parent) + self.logger = MyLogger("AvailChecker") + self.logger.log_info("Starting worker thread") + self.logger.log_info( + "Checking availability for " + + str(links) + + " with appnumber " + + str(appnumber) + + "..." + ) + self.links = links + self.appnumber = appnumber + self.books = books + self.logger.log_info( + f"Started worker with appnumber: {self.appnumber} and links: {self.links} and {len(self.books)} books..." + ) + time.sleep(2) + + def run(self): + self.db = Database() + state = 0 + count = 0 + for link in self.links: + self.logger.log_info("Processing entry: " + str(link)) + data = WebRequest().get_ppn(link).get_data() + transformer = BibTextTransformer("RDS") + rds = transformer.get_data(data).return_data("rds_availability") + + book_id = None + for item in rds.items: + sign = item.superlocation + loc = item.location + # print(item.location) + if self.appnumber in sign or self.appnumber in loc: + state = 1 + break + for book in self.books: + if book["bookdata"].signature == link: + book_id = book["id"] + break + self.logger.log_info(f"State of {link}: " + str(state)) + print("Updating availability of " + str(book_id) + " to " + str(state)) + self.db.setAvailability(book_id, state) + count += 1 + self.updateProgress.emit(count, len(self.links)) + self.updateSignal.emit(item.callnumber, state) + + self.logger.log_info("Worker thread finished") + # teminate thread + + self.quit() diff --git a/src/logic/threads_copy.py b/src/logic/threads_copy.py new file mode 100644 index 0000000..56d4339 --- /dev/null +++ b/src/logic/threads_copy.py @@ -0,0 +1,268 @@ +import threading +import time +import os +from PyQt6.QtCore import QThread, pyqtSignal + +from src.backend.database import Database +from src.logic.log import MyLogger +from src.transformers import RDS_AVAIL_DATA +from src.logic.webrequest import BibTextTransformer, WebRequest +import sqlite3 +from icecream import ic + + +class BookGrabber(QThread): + updateSignal = pyqtSignal(int, int) + + def __init__(self, filename): + super(BookGrabber, self).__init__(parent=None) + self.is_Running = True + self.logger = MyLogger("Worker") + self.logger.log_info("Starting worker thread") + self.data,self.app_id,self.prof_id,self.mode = self.readFile(filename) + + self.book_id = None + time.sleep(2) + + def readFile(self, filename): + with open(filename, "r") as file: + data = file.readlines() + app_id = data[0].strip() + prof_id = data[1].strip() + mode = data[2].strip() + data = data[3:] + return data, app_id, prof_id, mode + + # def resetValues(self): + # self.app_id = None + # self.prof_id = None + # self.mode = None + # self.data = None + # self.book_id = None + + def run(self): + 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 + 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( + "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.stop() + 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 = None, appnumber: int = None, parent=None, books=list[dict] + ): + if links is None: + links = [] + super().__init__(parent) + self.logger = MyLogger("AvailChecker") + self.logger.log_info("Starting worker thread") + self.logger.log_info( + "Checking availability for " + + str(links) + + " with appnumber " + + str(appnumber) + + "..." + ) + self.links = links + self.appnumber = appnumber + self.books = books + self.logger.log_info( + f"Started worker with appnumber: {self.appnumber} and links: {self.links} and {len(self.books)} books..." + ) + time.sleep(2) + + def run(self): + self.db = Database() + state = 0 + count = 0 + for link in self.links: + self.logger.log_info("Processing entry: " + str(link)) + data = WebRequest().get_ppn(link).get_data() + transformer = BibTextTransformer("RDS") + rds = transformer.get_data(data).return_data("rds_availability") + + book_id = None + for item in rds.items: + sign = item.superlocation + loc = item.location + # print(item.location) + if self.appnumber in sign or self.appnumber in loc: + state = 1 + break + for book in self.books: + if book["bookdata"].signature == link: + book_id = book["id"] + break + self.logger.log_info(f"State of {link}: " + str(state)) + print("Updating availability of " + str(book_id) + " to " + str(state)) + self.db.setAvailability(book_id, state) + count += 1 + self.updateProgress.emit(count, len(self.links)) + self.updateSignal.emit(item.callnumber, state) + + self.logger.log_info("Worker thread finished") + # teminate thread + + self.quit() + + +class AutoAdder(QThread): + updateSignal = pyqtSignal(int) + + setTextSignal = pyqtSignal(int) + progress = pyqtSignal(int) + + def __init__(self, data=None, app_id=None, prof_id=None, parent=None): + super().__init__(parent) + self.logger = MyLogger("AutoAdder") + self.data = data + self.app_id = app_id + self.prof_id = prof_id + + print("Launched AutoAdder") + print(self.data, self.app_id, self.prof_id) + + def run(self): + self.db = Database() + # show the dialog, start the thread to gather data and dynamically update progressbar and listwidget + self.logger.log_info("Starting worker thread") + item = 0 + for entry in self.data: + try: + # webdata = WebRequest().get_ppn(entry).get_data() + # bd = BibTextTransformer("ARRAY").get_data(webdata).return_data() + # bd.signature = entry + self.updateSignal.emit(item) + self.setTextSignal.emit(entry) + # qsleep + item += 1 + self.progress.emit(item) + print(item, len(self.data)) + time.sleep(1) + + except Exception as e: + print(e) + self.logger.log_exception( + f"The query failed with message {e} for signature {entry}" + ) + continue + if item == len(self.data): + self.logger.log_info("Worker thread finished") + # teminate thread + self.finished.emit() + + +class MockAvailCheck: + + def __init__( + self, links: list = [], appnumber: int = None, parent=None, books=list[dict] + ): + if links is None: + links = [] + super().__init__(parent) + self.logger = MyLogger("MockAvailChecker") + self.logger.log_info("Starting worker thread") + self.logger.log_info( + "Checking availability for " + + str(links) + + " with appnumber " + + str(appnumber) + + "..." + ) + self.links = links + self.appnumber = appnumber + self.books = books + + def run(self): + self.db = Database() + state = 0 + count = 0 + result = [] + for link in self.links: + self.logger.log_info("Processing entry: " + str(link)) + data = WebRequest().get_ppn(link).get_data() + transformer = BibTextTransformer("RDS") + rds = transformer.get_data(data).return_data("rds_availability") + + for item in rds.items: + sign = item.superlocation + loc = item.location + ic(item.location, item.superlocation) + if self.appnumber in sign or self.appnumber in loc: + state = 1 + book_id = None + for book in self.books: + if book["bookdata"].signature == link: + book_id = book["id"] + break + self.logger.log_info(f"State of {link}: " + str(state)) + print( + "lock acquired, updating availability of " + + str(book_id) + + " to " + + str(state) + ) + result.append((item.callnumber, state)) + count += 1 + return result + + self.logger.log_info("Worker thread finished") + # teminate thread