From f7c499ea6eae4143abe1aede1dfd95aa48a1bda8 Mon Sep 17 00:00:00 2001 From: WorldTeacher Date: Tue, 13 May 2025 15:49:52 +0200 Subject: [PATCH] Refactor logging setup across multiple modules to use loguru with consistent configuration - Updated logging initialization in MessageCalendar, admin_edit_prof, elsa_main, graph, iconLine, searchPage, and richtext modules to use loguru. - Changed log rotation and retention settings for log files to improve log management. - Replaced logger.debug/info calls with log.debug/info for consistency. - Fixed a typo in the searchPage UI and updated related references in the UI files. - Removed unused imports and cleaned up code for better readability. --- src/backend/create_file.py | 9 +- src/backend/database.py | 100 +++++----- src/backend/semester.py | 20 +- src/backend/thread_bookgrabber.py | 77 ++++---- src/backend/threads_autoadder.py | 23 +-- src/backend/threads_availchecker.py | 26 ++- src/logic/dataclass.py | 2 +- src/logic/webrequest.py | 47 +++-- src/logic/wordparser.py | 26 +-- src/transformers/transformers.py | 22 +-- src/ui/dialogs/__init__.py | 25 ++- src/ui/dialogs/elsa_add_entry.py | 2 +- src/ui/dialogs/login.py | 17 +- src/ui/dialogs/mail.py | 33 ++-- src/ui/dialogs/mailTemplate.py | 8 +- src/ui/dialogs/medienadder.py | 2 +- src/ui/dialogs/parsed_titles.py | 7 +- src/ui/dialogs/reminder.py | 2 +- src/ui/dialogs/settings.py | 22 +-- src/ui/semesterapparat_ui.ui | 2 +- src/ui/semesterapparat_ui_ui.py | 4 +- src/ui/userInterface.py | 178 +++++++++--------- src/ui/widgets/MessageCalendar.py | 14 +- src/ui/widgets/admin_edit_prof.py | 15 +- src/ui/widgets/elsa_main.py | 33 ++-- src/ui/widgets/graph.py | 17 +- src/ui/widgets/iconLine.py | 11 +- src/ui/widgets/searchPage.py | 38 ++-- .../widget_sources/search_statistic_page.ui | 58 +++--- .../search_statistic_page_ui.py | 35 ++-- src/utils/__init__.py | 2 - src/utils/richtext.py | 26 +-- 32 files changed, 412 insertions(+), 491 deletions(-) diff --git a/src/backend/create_file.py b/src/backend/create_file.py index 3921624..b19e1e0 100644 --- a/src/backend/create_file.py +++ b/src/backend/create_file.py @@ -4,18 +4,17 @@ from pathlib import Path from src.backend.database import Database -db = Database() import loguru import sys log = loguru.logger log.remove() -log.add("application.log", rotation="1 week", retention="1 month") -log.add( - sys.stdout, -) +log.add(sys.stdout) +log.add("logs/application.log", rotation="1 MB", retention="10 days") +db = Database() + def recreateFile(name: str, app_id: int, filetype: str, open: bool = True) -> Path: """ recreateFile creates a file from the database and opens it in the respective program, if the open parameter is set to True. diff --git a/src/backend/database.py b/src/backend/database.py index c5b79fb..0dfcbaf 100644 --- a/src/backend/database.py +++ b/src/backend/database.py @@ -24,18 +24,14 @@ from src.logic import ApparatData, BookData, Prof, Apparat, ELSA from src.logic.constants import SEMAP_MEDIA_ACCOUNTS from .semester import Semester from string import ascii_lowercase as lower, digits, punctuation +import loguru import sys -from loguru import logger as log -logger = log -logger.remove() -logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True) -log.add( - "logs/database.log", -) +log = loguru.logger +log.remove() +log.add(sys.stdout) +log.add("logs/application.log", rotation="1 MB", retention="10 days") -# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO") -logger.add(sys.stdout) ascii_lowercase = lower + digits + punctuation @@ -58,7 +54,7 @@ class Database: if db_path is None: self.db_path = self.database.path + self.database.name self.db_path = self.db_path.replace("~", str(Path.home())) - logger.debug(self.db_path) + log.debug(self.db_path) else: self.db_path = db_path self.checkDatabaseStatus() @@ -69,10 +65,10 @@ class Database: path = os.path.abspath(path) if not os.path.exists(path): # create path - # logger.debug(path) + # log.debug(path) os.makedirs(path) if self.get_db_contents() == []: - logger.critical("Database does not exist, creating tables") + log.critical("Database does not exist, creating tables") self.create_tables() self.insertSubjects() @@ -155,12 +151,12 @@ class Database: """ conn = self.connect() cursor = conn.cursor() - logger.debug(f"Inserting {params} into database with query {query}") + log.debug(f"Inserting {params} into database with query {query}") cursor.execute(query, params) conn.commit() self.close_connection(conn) - @logger.catch + @log.catch def query_db( self, query: str, @@ -195,7 +191,7 @@ class Database: # log_message = f"Querying database with query {query}" if "INTO user" in query: log_message = f"Querying database with query {query}" - # logger.debug(f"DB Query: {log_message}") + # log.debug(f"DB Query: {log_message}") log.debug(log_message) try: cursor.execute(query, args) @@ -203,7 +199,7 @@ class Database: conn.commit() self.close_connection(conn) except sql.OperationalError as e: - logger.error(f"Error in query: {e}") + log.error(f"Error in query: {e}") return None return (rv[0] if rv else None) if one else rv @@ -219,7 +215,7 @@ class Database: app_id (str): The apparat id where the book should be added to prof_id (str): The id of the professor where the book should be added to. """ - logger.info(f"Adding book {bookdata.signature} to database") + log.info(f"Adding book {bookdata.signature} to database") if app_id is None or prof_id is None: raise ValueError("Apparate ID or Prof ID is None") conn = self.connect() @@ -227,12 +223,12 @@ class Database: t_query = ( f"SELECT bookdata FROM media WHERE app_id={app_id} AND prof_id={prof_id}" ) - logger.debug(t_query) - # # logger.debug(t_query) + log.debug(t_query) + # # log.debug(t_query) result = cursor.execute(t_query).fetchall() result = [BookData().from_string(i[0]) for i in result] if bookdata in result: - # logger.debug("Bookdata already in database") + # log.debug("Bookdata already in database") # check if the book was deleted in the apparat query = ( "SELECT deleted FROM media WHERE app_id=? AND prof_id=? AND bookdata=?" @@ -240,7 +236,7 @@ class Database: params = (app_id, prof_id, json.dumps(asdict(bookdata), ensure_ascii=False)) result = cursor.execute(query, params).fetchone() if result[0] == 1: - # logger.debug("Book was deleted, updating bookdata") + # log.debug("Book was deleted, updating bookdata") query = "UPDATE media SET deleted=0 WHERE app_id=? AND prof_id=? AND bookdata=?" params = ( app_id, @@ -258,7 +254,7 @@ class Database: params = (converted, app_id, prof_id, 0) cursor.execute(query, params) logMessage = f"Added book with signature {bookdata.signature} to database, data: {converted}" - logger.info(logMessage) + log.info(logMessage) conn.commit() self.close_connection(conn) @@ -327,7 +323,7 @@ class Database: list[tuple[BookData, int]]: A list of tuples containing the wrapped Metadata and the id of the book """ rdata = self.query_db("SELECT * FROM media WHERE deleted=0") - # logger.debug(rdata, len(rdata)) + # log.debug(rdata, len(rdata)) mode = 0 if len(data) == 1: if "signature" in data.keys(): @@ -355,7 +351,7 @@ class Database: and data["title"] in bookdata.title ): ret.append((bookdata, app_id, prof_id)) - # logger.debug(ret) + # log.debug(ret) return ret def setAvailability(self, book_id: str, available: str): @@ -516,7 +512,7 @@ class Database: delete=False, dir=tempdir_path, mode="wb", suffix=f".{filetype}" ) file.write(blob) - # logger.debug("file created") + # log.debug("file created") return file.name def getFiles(self, app_id: Union[str, int], prof_id: int) -> list[tuple]: @@ -544,7 +540,7 @@ class Database: return [i[0] for i in data] def insertSubjects(self): - # logger.debug("Inserting subjects") + # log.debug("Inserting subjects") subjects = [ "Biologie", "Chemie", @@ -660,7 +656,7 @@ class Database: Args: message_id (str): the id of the message """ - logger.debug(f"Deleting message with id {message_id}") + log.debug(f"Deleting message with id {message_id}") self.query_db("DELETE FROM messages WHERE id=?", (message_id,)) # Prof data @@ -827,7 +823,7 @@ class Database: ) numbers = [i[0] for i in numbers] numbers.sort() - logger.info(f"Currently used apparat numbers: {numbers}") + log.info(f"Currently used apparat numbers: {numbers}") return numbers def setNewSemesterDate(self, app_id: Union[str, int], newDate, dauerapp=False): @@ -881,22 +877,22 @@ class Database: Returns: Optional[int]: the id of the apparat """ - logger.debug(apparat) + log.debug(apparat) app = apparat.apparat prof = apparat.prof present_prof = self.getProfByName(prof.name()) prof_id = present_prof.id - logger.debug(present_prof) + log.debug(present_prof) app_id = self.getApparatId(app.name) if app_id: return AppPresentError(app_id) if not prof_id: - logger.debug("prof id not present, creating prof with data", prof) + log.debug("prof id not present, creating prof with data", prof) prof_id = self.createProf(prof) - logger.debug(prof_id) + log.debug(prof_id) query = f"INSERT OR IGNORE INTO semesterapparat (appnr, name, erstellsemester, dauer, prof_id, fach,deletion_status,konto) VALUES ('{app.appnr}', '{app.name}', '{app.created_semester}', '{app.eternal}', {prof_id}, '{app.subject}', '{0}', '{SEMAP_MEDIA_ACCOUNTS[app.appnr]}')" - logger.debug(query) + log.debug(query) self.query_db(query) return None @@ -914,7 +910,7 @@ class Database: ) ret = [] for i in data: - logger.debug(i) + log.debug(i) ret.append(Apparat().from_tuple(i)) return ret @@ -996,7 +992,7 @@ class Database: app_id (Union[str, int]): the id of the apparat semester (str): the semester the apparat should be deleted from """ - logger.info(f"Deleting apparat with id {app_id} in semester {semester}") + log.info(f"Deleting apparat with id {app_id} in semester {semester}") self.query_db( "UPDATE semesterapparat SET deletion_status=1, deleted_date=? WHERE appnr=?", (semester, app_id), @@ -1054,7 +1050,7 @@ class Database: apparat_data.apparat.apparat_id_adis, apparat_data.apparat.appnr, ) - logger.debug(f"Updating apparat with query {query} and params {params}") + log.debug(f"Updating apparat with query {query} and params {params}") self.query_db(query, params) def checkApparatExists(self, app_name: str): @@ -1106,7 +1102,7 @@ class Database: Returns: list: the result of the query """ - logger.debug(f"Query: {query}") + log.debug(f"Query: {query}") conn = self.connect() cursor = conn.cursor() result = cursor.execute(query).fetchall() @@ -1119,7 +1115,7 @@ class Database: result_a = tuple(result_a) result[result.index(orig_value)] = result_a self.close_connection(conn) - logger.debug(f"Query result: {result}") + log.debug(f"Query result: {result}") return result if "deletable" in kwargs.keys(): @@ -1134,9 +1130,9 @@ class Database: kwargs["dauer"] = kwargs["dauer"].replace("Ja", "1").replace("Nein", "0") query = "SELECT * FROM semesterapparat WHERE " for key, value in kwargs.items() if kwargs.items() is not None else {}: - # logger.debug(key, value) + # log.debug(key, value) query += f"{key}='{value}' AND " - # logger.debug(query) + # log.debug(query) # remove deletesemester part from normal query, as this will be added to the database upon deleting the apparat if "deletesemester" in kwargs.keys(): query = query.replace( @@ -1152,24 +1148,24 @@ class Database: query = query.replace( f"endsemester='{kwargs['endsemester']}' AND ", "xyz" ) - # logger.debug("replaced") + # log.debug("replaced") query = query.replace( "xyz", f"(erstellsemester='{kwargs['endsemester']}' OR verlängerung_bis='{kwargs['endsemester']}') AND ", ) # remove all x="" parts from the query where x is a key in kwargs - logger.info(f"Query before: {query}") + log.info(f"Query before: {query}") query = query.strip() query = query[:-4] - logger.info(f"Query after: {query}") + log.info(f"Query after: {query}") # check if query ends with lowercase letter or a '. if not, remove last symbol and try again while query[-1] not in ascii_lowercase and query[-1] != "'": query = query[:-1] query = query.strip() - # logger.debug(query) + # log.debug(query) res = __query(query) - # logger.debug(res) + # log.debug(res) return res # Admin data @@ -1457,7 +1453,7 @@ class Database: blob = self.query_db( "SELECT fileblob FROM elsa_files WHERE filename=?", (filename,), one=True )[0] - # logger.debug(blob) + # log.debug(blob) tempdir = self.database.temp tempdir = tempdir.replace("~", str(Path.home())) tempdir_path = Path(tempdir) @@ -1467,7 +1463,7 @@ class Database: delete=False, dir=tempdir_path, mode="wb", suffix=f".{filetype}" ) file.write(blob) - # logger.debug("file created") + # log.debug("file created") return file.name def getElsaApparats(self) -> ELSA: @@ -1517,7 +1513,7 @@ class Database: ### def createProf(self, profdata: Prof): - logger.debug(profdata) + log.debug(profdata) conn = self.connect() cursor = conn.cursor() fname = profdata.firstname @@ -1528,7 +1524,7 @@ class Database: title = profdata.title query = f"INSERT INTO prof (fname, lname, fullname, mail, telnr,titel) VALUES ('{fname}','{lname}','{fullname}','{mail}','{telnr}','{title}')" - logger.debug(query) + log.debug(query) cursor.execute(query) conn.commit() @@ -1573,7 +1569,7 @@ class Database: else: fullname = profdata.name() query = f"SELECT id FROM prof WHERE fullname = '{fullname}'" - logger.debug(query) + log.debug(query) cursor.execute(query) result = cursor.fetchone() @@ -1591,7 +1587,7 @@ class Database: conn = self.connect() cursor = conn.cursor() query = f"SELECT * FROM prof WHERE fullname = '{fullname}'" - logger.debug(query) + log.debug(query) result = cursor.execute(query).fetchone() if result: @@ -1612,7 +1608,7 @@ class Database: query = f"SELECT prof_id from semesterapparat WHERE appnr = '{apprarat_id}' and deletion_status = 0" data = self.query_db(query) if data: - logger.info("Prof ID: " + str(data[0][0])) + log.info("Prof ID: " + str(data[0][0])) return data[0][0] else: return None diff --git a/src/backend/semester.py b/src/backend/semester.py index 4e675ac..d2fb51e 100644 --- a/src/backend/semester.py +++ b/src/backend/semester.py @@ -1,27 +1,25 @@ import datetime from dataclasses import dataclass +import loguru import sys -from loguru import logger as log -logger = log -logger.remove() -logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True) +log = loguru.logger +log.remove() +log.add(sys.stdout) +log.add("logs/application.log", rotation="1 MB", retention="10 days") -# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO") -logger.add(sys.stdout) - @dataclass class Semester: - logger.debug("Semester class loaded") + log.debug("Semester class loaded") _year: int | None = str(datetime.datetime.now().year)[2:] _semester: str | None = None _month: int | None = datetime.datetime.now().month value: str = None - logger.debug( + log.debug( f"Initialized Semester class with values: month: {_month}, semester: {_semester}, year {_year}" ) @@ -45,7 +43,7 @@ class Semester: else: self._semester = "SoSe" - @logger.catch + @log.catch def computeValue(self): # year is only last two digits year = self._year @@ -57,7 +55,7 @@ class Semester: valueyear = str(year) + "/" + str(year + 1) self.value = f"{self._semester} {valueyear}" - @logger.catch + @log.catch def offset(self, value: int) -> str: """Generate a new Semester object by offsetting the current semester by a given value diff --git a/src/backend/thread_bookgrabber.py b/src/backend/thread_bookgrabber.py index ac6ce87..5d5ab49 100644 --- a/src/backend/thread_bookgrabber.py +++ b/src/backend/thread_bookgrabber.py @@ -3,22 +3,17 @@ from PyQt6.QtCore import pyqtSignal as Signal from src.backend import Database from src.logic.webrequest import BibTextTransformer, WebRequest +import loguru import sys -from loguru import logger as log -logger = log -logger.remove() -logger.add( - "logs/bookgrabber_thread.log", rotation="1 week", retention="1 month", enqueue=True -) -log.add( - "logs/application.log", - rotation="1 day", - compression="zip", -) +log = loguru.logger +log.remove() +log.add(sys.stdout) +log.add("logs/application.log", rotation="1 MB", retention="10 days") + # logger.add(sys.stderr, format="{time} {level} {message}", level="INFO") -logger.add(sys.stdout) +log.add(sys.stdout) class BookGrabber(QThread): @@ -28,7 +23,7 @@ class BookGrabber(QThread): def __init__(self): super(BookGrabber, self).__init__(parent=None) self.is_Running = True - logger.info("Starting worker thread") + log.info("Starting worker thread") self.data = [] self.app_id = None self.prof_id = None @@ -49,21 +44,21 @@ class BookGrabber(QThread): self.data: list[str] = data self.use_any = any_book self.use_exact = exact - logger.info(f"Working on {len(self.data)} entries") + log.info(f"Working on {len(self.data)} entries") self.tstate = (self.app_id, self.prof_id, self.mode, self.data) - logger.debug("State: " + str(self.tstate)) + log.debug("State: " + str(self.tstate)) self.request.set_apparat(self.app_id) - # logger.debug(self.tstate) + # log.debug(self.tstate) def run(self): self.db = Database() item = 0 iterdata = self.data - # logger.debug(iterdata) + # log.debug(iterdata) for entry in iterdata: - # logger.debug(entry) - logger.info("Processing entry: {}", entry) + # log.debug(entry) + log.info("Processing entry: {}", entry) webdata = self.request.get_ppn(entry) if self.use_any: @@ -74,12 +69,12 @@ class BookGrabber(QThread): continue bd = BibTextTransformer(self.mode) - logger.debug(webdata) + log.debug(webdata) if self.mode == "ARRAY": if self.use_exact: bd = bd.use_signature(entry) bd = bd.get_data(webdata).return_data() - logger.debug(bd) + log.debug(bd) if bd is None: # bd = BookData continue @@ -92,29 +87,29 @@ class BookGrabber(QThread): self.db.addBookToDatabase(bd, self.app_id, self.prof_id) # get latest book id self.book_id = self.db.getLastBookId() - logger.info("Added book to database") + log.info("Added book to database") state = 0 for result in transformer.RDS_DATA: - # logger.debug(result.RDS_LOCATION) + # log.debug(result.RDS_LOCATION) if str(self.app_id) in result.RDS_LOCATION: state = 1 break - logger.info(f"State of {entry}: {state}") - logger.debug( + log.info(f"State of {entry}: {state}") + log.debug( "updating availability of " + str(self.book_id) + " to " + str(state) ) try: self.db.setAvailability(self.book_id, state) - logger.debug("Added book to database") + log.debug("Added book to database") except Exception as e: - logger.error(f"Failed to update availability: {e}") - logger.debug("Failed to update availability: " + str(e)) + log.error(f"Failed to update availability: {e}") + log.debug("Failed to update availability: " + str(e)) # time.sleep(5) item += 1 self.updateSignal.emit(item, len(self.data)) - logger.info("Worker thread finished") + log.info("Worker thread finished") # self.done.emit() self.quit() @@ -129,7 +124,7 @@ class BookGrabberTest(QThread): def __init__(self, appnr: int): super(BookGrabberTest, self).__init__(parent=None) self.is_Running = True - logger.info("Starting worker thread") + log.info("Starting worker thread") self.data = None self.app_id = None self.prof_id = None @@ -150,19 +145,19 @@ class BookGrabberTest(QThread): self.data = data self.use_any = any_book self.use_exact = exact - logger.info(f"Working on {len(self.data)} entries") + log.info(f"Working on {len(self.data)} entries") self.tstate = (self.app_id, self.prof_id, self.mode, self.data) - logger.debug("State: " + str(self.tstate)) - # logger.debug(self.tstate) + log.debug("State: " + str(self.tstate)) + # log.debug(self.tstate) def run(self): item = 0 iterdata = self.data - # logger.debug(iterdata) + # log.debug(iterdata) for entry in iterdata: - # logger.debug(entry) + # log.debug(entry) signature = str(entry) - logger.info("Processing entry: " + signature) + log.info("Processing entry: " + signature) webdata = WebRequest().set_apparat(self.app_id).get_ppn(entry) if self.use_any: @@ -187,22 +182,22 @@ class BookGrabberTest(QThread): # confirm lock is acquired # get latest book id - logger.info("Added book to database") + log.info("Added book to database") state = 0 for result in transformer.RDS_DATA: - # logger.debug(result.RDS_LOCATION) + # log.debug(result.RDS_LOCATION) if str(self.app_id) in result.RDS_LOCATION: state = 1 break - logger.info(f"State of {signature}: {state}") - # logger.debug("updating availability of " + str(self.book_id) + " to " + str(state)) + log.info(f"State of {signature}: {state}") + # log.debug("updating availability of " + str(self.book_id) + " to " + str(state)) self.results.append(bd) # time.sleep(5) item += 1 self.updateSignal.emit(item, len(self.data)) - logger.info("Worker thread finished") + log.info("Worker thread finished") # self.done.emit() self.quit() diff --git a/src/backend/threads_autoadder.py b/src/backend/threads_autoadder.py index 2b60474..2ceec0e 100644 --- a/src/backend/threads_autoadder.py +++ b/src/backend/threads_autoadder.py @@ -5,21 +5,14 @@ from PyQt6.QtCore import QThread from PyQt6.QtCore import pyqtSignal as Signal from src.backend import Database -from loguru import logger as log +import loguru import sys -logger = log -logger.remove() -logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True) -logger.add( - "logs/autoadder.log", - compression="zip", - rotation="1 week", - retention="1 month", -) +log = loguru.logger +log.remove() +log.add(sys.stdout) +log.add("logs/application.log", rotation="1 MB", retention="10 days") -# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO") -logger.add(sys.stdout) # from src.transformers import RDS_AVAIL_DATA @@ -42,7 +35,7 @@ class AutoAdder(QThread): def run(self): self.db = Database() # show the dialog, start the thread to gather data and dynamically update progressbar and listwidget - logger.info("Starting worker thread") + log.info("Starting worker thread") item = 0 for entry in self.data: try: @@ -54,11 +47,11 @@ class AutoAdder(QThread): except Exception as e: # print(e) - logger.exception( + log.exception( f"The query failed with message {e} for signature {entry}" ) continue if item == len(self.data): - logger.info("Worker thread finished") + log.info("Worker thread finished") # teminate thread self.finished.emit() diff --git a/src/backend/threads_availchecker.py b/src/backend/threads_availchecker.py index 51227d1..5aebb4f 100644 --- a/src/backend/threads_availchecker.py +++ b/src/backend/threads_availchecker.py @@ -9,18 +9,14 @@ from src.backend.database import Database from src.logic.webrequest import BibTextTransformer, WebRequest # from src.transformers import RDS_AVAIL_DATA -from loguru import logger as log +import loguru import sys -logger = log -logger.remove() -logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True) -log.add( - "logs/availthread.log", -) +log = loguru.logger +log.remove() +log.add(sys.stdout) +log.add("logs/application.log", rotation="1 MB", retention="10 days") -# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO") -logger.add(sys.stdout) class AvailChecker(QThread): @@ -33,8 +29,8 @@ class AvailChecker(QThread): if links is None: links = [] super().__init__(parent) - logger.info("Starting worker thread") - logger.info( + log.info("Starting worker thread") + log.info( "Checking availability for " + str(links) + " with appnumber " @@ -44,7 +40,7 @@ class AvailChecker(QThread): self.links = links self.appnumber = appnumber self.books = books - logger.info( + log.info( f"Started worker with appnumber: {self.appnumber} and links: {self.links} and {len(self.books)} books..." ) time.sleep(2) @@ -54,7 +50,7 @@ class AvailChecker(QThread): state = 0 count = 0 for link in self.links: - logger.info("Processing entry: " + str(link)) + log.info("Processing entry: " + str(link)) data = WebRequest().set_apparat(self.appnumber).get_ppn(link).get_data() transformer = BibTextTransformer("RDS") rds = transformer.get_data(data).return_data("rds_availability") @@ -71,14 +67,14 @@ class AvailChecker(QThread): if book["bookdata"].signature == link: book_id = book["id"] break - logger.info(f"State of {link}: " + str(state)) + 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) - logger.info("Worker thread finished") + log.info("Worker thread finished") # teminate thread self.quit() diff --git a/src/logic/dataclass.py b/src/logic/dataclass.py index 51a88e1..a807f87 100644 --- a/src/logic/dataclass.py +++ b/src/logic/dataclass.py @@ -1,4 +1,4 @@ -import re + from dataclasses import dataclass, field from enum import Enum diff --git a/src/logic/webrequest.py b/src/logic/webrequest.py index 3762e52..5626ccf 100644 --- a/src/logic/webrequest.py +++ b/src/logic/webrequest.py @@ -4,25 +4,20 @@ from bs4 import BeautifulSoup # import sleep_and_retry decorator to retry requests from ratelimit import limits, sleep_and_retry -from typing import Union, Any, Literal, Optional +from typing import Union, Any, Optional from src.logic.dataclass import BookData from src.transformers import ARRAYData, BibTeXData, COinSData, RDSData, RISData from src.transformers.transformers import RDS_AVAIL_DATA, RDS_GENERIC_DATA +import loguru import sys -from loguru import logger as log - -logger = log -logger.remove() -logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True) -log.add( - f"logs/webrequest.log", - rotation="1 day", - compression="zip", -) +log = loguru.logger +log.remove() +log.add(sys.stdout) +log.add("logs/application.log", rotation="1 MB", retention="10 days") # logger.add(sys.stderr, format="{time} {level} {message}", level="INFO") -logger.add(sys.stdout) + API_URL = "https://rds.ibs-bw.de/phfreiburg/opac/RDSIndexrecord/{}/" @@ -53,20 +48,20 @@ class WebRequest: self.ppn = None self.data = None self.timeout = 5 - logger.info("Initialized WebRequest") + log.info("Initialized WebRequest") @property def use_any_book(self): """use any book that matches the search term""" self.use_any = True - logger.info("Using any book") + log.info("Using any book") return self def set_apparat(self, apparat: int): self.apparat = apparat if int(self.apparat) < 10: self.apparat = f"0{self.apparat}" - logger.info(f"Set apparat to {self.apparat}") + log.info(f"Set apparat to {self.apparat}") return self def get_ppn(self, signature: str): @@ -100,12 +95,12 @@ class WebRequest: response = requests.get(link, timeout=self.timeout) return response.text except requests.exceptions.RequestException as e: - logger.error(f"Request failed: {e}") + log.error(f"Request failed: {e}") return None def get_data(self) -> Union[list[str], None]: links = self.get_book_links(self.ppn) - logger.debug(f"Links: {links}") + log.debug(f"Links: {links}") return_data: list[str] = [] for link in links: result: str = self.search(link) # type:ignore @@ -118,7 +113,7 @@ class WebRequest: item_location = location.find( "div", class_="col-xs-12 col-md-7 col-lg-8 rds-dl-panel" ).text.strip() - logger.debug(f"Item location: {item_location}") + log.debug(f"Item location: {item_location}") if self.use_any: pre_tag = soup.find_all("pre") if pre_tag: @@ -127,7 +122,7 @@ class WebRequest: return_data.append(data) return return_data else: - logger.error("No
 tag found")
+                            log.error("No 
 tag found")
                             raise ValueError("No 
 tag found")
                     elif f"Semesterapparat-{self.apparat}" in item_location:
                         pre_tag = soup.find_all("pre")
@@ -138,10 +133,10 @@ class WebRequest:
                                 return_data.append(data)
                             return return_data
                         else:
-                            logger.error("No 
 tag found")
+                            log.error("No 
 tag found")
                             return return_data
                     else:
-                        logger.error(
+                        log.error(
                             f"Signature {self.signature} not found in {item_location}"
                         )
                         # return_data = []
@@ -166,7 +161,7 @@ class WebRequest:
                             return_data.append(data)
                         return return_data
                     else:
-                        logger.error("No 
 tag found")
+                        log.error("No 
 tag found")
                         return return_data
 
 
@@ -184,7 +179,7 @@ class BibTextTransformer:
         self.field = None
         self.signature = None
         if mode not in self.valid_modes:
-            logger.error(f"Mode {mode} not valid")
+            log.error(f"Mode {mode} not valid")
             raise ValueError(f"Mode {mode} not valid")
         self.data = None
         # self.bookdata = BookData(**self.data)
@@ -274,7 +269,7 @@ class BibTextTransformer:
 
 def cover(isbn):
     test_url = f"https://www.buchhandel.de/cover/{isbn}/{isbn}-cover-m.jpg"
-    # logger.debug(test_url)
+    # log.debug(test_url)
     data = requests.get(test_url, stream=True)
     return data.content
 
@@ -284,8 +279,8 @@ def get_content(soup, css_class):
 
 
 if __name__ == "__main__":
-    # logger.debug("main")
+    # log.debug("main")
     link = "CU 8500 K64"
     data = WebRequest(71).get_ppn(link).get_data()
     bib = BibTextTransformer("ARRAY").get_data().return_data()
-    logger.debug(bib)
+    log.debug(bib)
diff --git a/src/logic/wordparser.py b/src/logic/wordparser.py
index e4928f6..c0ad35a 100644
--- a/src/logic/wordparser.py
+++ b/src/logic/wordparser.py
@@ -1,23 +1,17 @@
 import pandas as pd
 from docx import Document
 from dataclasses import dataclass
-import sys
-from loguru import logger as log
 from src.backend import Semester
 from typing import Union, Any
 
-logger = log
-logger.remove()
-logger.add("logs/wordparser.log", rotation="1 week", retention="1 month", enqueue=True)
-log.add(
-    f"logs/application.log",
-    rotation="1 day",
-    compression="zip",
-    enqueue=True,
-)
+import loguru
+import sys
+
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
 
 
 letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
@@ -218,12 +212,12 @@ def elsa_word_to_csv(path: str):
     data = [
         row for row in df.itertuples(index=False, name=None) if row != tuples[doctype]
     ]
-    # logger.debug(data)
+    # log.debug(data)
     return tuple_to_dict(data, doctype), doctype
 
 
 def word_to_semap(word_path: str) -> SemapDocument:
-    logger.info("Parsing Word Document {}", word_path)
+    log.info("Parsing Word Document {}", word_path)
     semap = SemapDocument()
     df = word_docx_to_csv(word_path)
     apparatdata = df[0]
@@ -258,7 +252,7 @@ def word_to_semap(word_path: str) -> SemapDocument:
             continue
         else:
             booklist.append(book)
-    logger.info("Found {} books", len(booklist))
+    log.info("Found {} books", len(booklist))
     semap.books = booklist
 
     return semap
diff --git a/src/transformers/transformers.py b/src/transformers/transformers.py
index 151591a..98d5758 100644
--- a/src/transformers/transformers.py
+++ b/src/transformers/transformers.py
@@ -8,19 +8,13 @@ from typing import Any, List
 
 
 from src.logic.dataclass import BookData
+import loguru
 import sys
-from loguru import logger as log
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
-log.add(
-    "logs/transformers.log",
-    enqueue=True,
-)
-
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
 
 ###Pydatnic models
@@ -143,8 +137,8 @@ class ARRAYData:
                 return data
 
             except Exception:
-                # # logger.debug(f"ARRAYData.transform failed, {source}, {search}")
-                logger.exception(f"ARRAYData.transform failed, no string {search}")
+                # # log.debug(f"ARRAYData.transform failed, {source}, {search}")
+                log.exception(f"ARRAYData.transform failed, no string {search}")
                 return ""
 
         def _get_list_entry(source: str, search: str, entry: str) -> str:
@@ -521,4 +515,4 @@ if __name__ == "__main__":
 
     ret = RDSData().transform(data)
     data = ret.return_data("rds_availability")
-    # logger.debug(data)
+    # log.debug(data)
diff --git a/src/ui/dialogs/__init__.py b/src/ui/dialogs/__init__.py
index d5a2d26..1940b77 100644
--- a/src/ui/dialogs/__init__.py
+++ b/src/ui/dialogs/__init__.py
@@ -1,32 +1,31 @@
 __all__ = [
-    "add_bookdata_ui",
-    "edit_bookdata_ui",
-    "login_ui",
+    "BookDataUI",
+    "LoginDialog",
     "Mail_Dialog",
     "MailTemplateDialog",
-    "medienadder_ui",
-    "parsed_titles_ui",
+    "MedienAdder",
+    "ParsedTitles",
     "popus_confirm",
-    "reminder_ui",
-    "Settings",
+    "ReminderDialog",
     "About",
     "ElsaGenConfirm",
     "ElsaAddEntry",
     "ApparatExtendDialog",
     "DocumentPrintDialog",
+    "Settings",
 ]
-from .bookdata import BookDataUI as edit_bookdata_ui
-from .login import LoginDialog as login_ui
+from .bookdata import BookDataUI
+from .login import LoginDialog
 from .mail import Mail_Dialog
 from .mailTemplate import MailTemplateDialog
-from .medienadder import MedienAdder as medienadder_ui
-from .parsed_titles import ParsedTitles as parsed_titles_ui
+from .medienadder import MedienAdder
+from .parsed_titles import ParsedTitles
 from .popup_confirm import ConfirmDialog as popus_confirm
-from .reminder import ReminderDialog as reminder_ui
+from .reminder import ReminderDialog
 from .about import About
 from .elsa_gen_confirm import ElsaGenConfirm
 from .elsa_add_entry import ElsaAddEntry
 from .app_ext import ApparatExtendDialog
-from .docuprint import DocumentPrintDialog, launch
+from .docuprint import DocumentPrintDialog
 
 from .settings import Settings
diff --git a/src/ui/dialogs/elsa_add_entry.py b/src/ui/dialogs/elsa_add_entry.py
index d068d33..597718e 100644
--- a/src/ui/dialogs/elsa_add_entry.py
+++ b/src/ui/dialogs/elsa_add_entry.py
@@ -118,7 +118,7 @@ class ElsaAddEntry(QtWidgets.QDialog, Ui_Dialog):
         if table["type"] == "zs":
             book = zot.createBook(table["isbn"])
             res_key = zot.createJournalArticle(book, table)
-            logger.debug(book)
+            log.debug(book)
             a_lastname = table["section_author"].split(";")[0].strip().split(",")[0]
             a_firstname = table["section_author"].split(";")[0].strip().split(",")[1]
             author = f"{a_lastname}, {a_firstname[0]}"
diff --git a/src/ui/dialogs/login.py b/src/ui/dialogs/login.py
index 0d5d184..e1e563e 100644
--- a/src/ui/dialogs/login.py
+++ b/src/ui/dialogs/login.py
@@ -6,18 +6,15 @@ from PyQt6 import QtCore, QtWidgets
 from src.backend.admin_console import AdminCommands
 from src.backend.database import Database
 
-from .dialog_sources.Ui_login import Ui_Dialog
+from .dialog_sources.login_ui import Ui_Dialog
 import sys
-from loguru import logger as log
+import loguru
 from src import Icon
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
-
-
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
 
 class LoginDialog(Ui_Dialog):
@@ -86,7 +83,7 @@ class LoginDialog(Ui_Dialog):
         if self.db.login(username, hashed_password):
             self.lresult = 1  # Indicate successful login
             self.lusername = username
-            logger.success(f"User {username} logged in.")
+            log.success(f"User {username} logged in.")
             self.dialog.accept()
 
         else:
diff --git a/src/ui/dialogs/mail.py b/src/ui/dialogs/mail.py
index 9491823..d7e0362 100644
--- a/src/ui/dialogs/mail.py
+++ b/src/ui/dialogs/mail.py
@@ -8,21 +8,14 @@ from src import Icon, settings as config
 
 from .dialog_sources.Ui_mail_preview import Ui_eMailPreview as MailPreviewDialog
 from .mailTemplate import MailTemplateDialog
+import loguru
 import sys
-from loguru import logger as log
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
-log.add(
-    "logs/mail.log",
-    rotation="1 day",
-    compression="zip",
-    enqueue=True,
-)
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
 
 
 empty_signature = """
@@ -60,7 +53,7 @@ class Mail_Dialog(QtWidgets.QDialog, MailPreviewDialog):
         super().__init__(parent)
         self.setupUi(self)
 
-        logger.info("Setting up mail dialog")
+        log.info("Setting up mail dialog")
         self.appid = app_id
         self.appname = app_name
         self.subject = app_subject
@@ -92,7 +85,7 @@ class Mail_Dialog(QtWidgets.QDialog, MailPreviewDialog):
         self.btn_okay.clicked.connect(self.createAndSendMail)
 
     def open_new_template(self):
-        logger.info("Opening new template dialog")
+        log.info("Opening new template dialog")
         # TODO: implement new mail template dialog
         dialog = MailTemplateDialog()
         dialog.updateSignal.connect(self.load_mail_templates)
@@ -111,9 +104,9 @@ Tel.: 0761/682-778 | 07617682-545"""
 
     def load_mail_templates(self):
         # print("loading mail templates")
-        logger.info("Loading mail templates")
+        log.info("Loading mail templates")
         mail_templates = os.listdir("mail_vorlagen")
-        logger.info(f"Mail templates: {mail_templates}")
+        log.info(f"Mail templates: {mail_templates}")
         self.comboBox.clear()
         for template in mail_templates:
             self.comboBox.addItem(template)
@@ -132,10 +125,10 @@ Tel.: 0761/682-778 | 07617682-545"""
             return f"Guten Tag {name},"
 
     def set_mail(self):
-        logger.info("Setting mail")
+        log.info("Setting mail")
         email_template = self.comboBox.currentText()
         if email_template == "":
-            logger.debug("No mail template selected")
+            log.debug("No mail template selected")
             return
         with open(f"mail_vorlagen/{email_template}", "r", encoding="utf-8") as f:
             mail_template = f.read()
@@ -160,7 +153,7 @@ Tel.: 0761/682-778 | 07617682-545"""
         self.mail_body.setHtml(mail_html)
 
     def createAndSendMail(self):
-        logger.info("Sending mail")
+        log.info("Sending mail")
         import smtplib
         from email.mime.multipart import MIMEMultipart
         from email.mime.text import MIMEText
@@ -197,7 +190,7 @@ Tel.: 0761/682-778 | 07617682-545"""
             # print("Mail sent")
             # end active process
             server.quit()
-        logger.info("Mail sent, closing connection to server and dialog")
+        log.info("Mail sent, closing connection to server and dialog")
         # close the dialog
 
         self.accept()
diff --git a/src/ui/dialogs/mailTemplate.py b/src/ui/dialogs/mailTemplate.py
index 7bc77b3..9c55b7c 100644
--- a/src/ui/dialogs/mailTemplate.py
+++ b/src/ui/dialogs/mailTemplate.py
@@ -52,7 +52,7 @@ class MailTemplateDialog(QtWidgets.QDialog, NewMailTemplateDesignerDialog):
         self.buttonBox.button(
             QtWidgets.QDialogButtonBox.StandardButton.Cancel
         ).clicked.connect(self.closeNow)
-        logger.info("Mail template dialog setup complete")
+        log.info("Mail template dialog setup complete")
 
     def save_template(self):
         # print("save triggered")
@@ -66,11 +66,11 @@ class MailTemplateDialog(QtWidgets.QDialog, NewMailTemplateDesignerDialog):
         dialog.setWindowIcon(Icon("save").icon)
         save = dialog.exec()
         template_name = dialog.textValue()
-        logger.info("Saving template")
+        log.info("Saving template")
         if template_name != "" and save == 1:
             template = template_name + ".eml"
             if template in os.listdir("mail_vorlagen"):
-                logger.error("Template already exists")
+                log.error("Template already exists")
                 # warning dialog
                 dialog = QtWidgets.QMessageBox()
                 dialog.setIcon(QtWidgets.QMessageBox.Icon.Warning)
@@ -110,7 +110,7 @@ Content-Transfer-Encoding: 8bit
                 f.write(mail)
             self.updateSignal.emit()
             self.close()
-            logger.success(f"Template {template} saved successfully")
+            log.success(f"Template {template} saved successfully")
         else:
             # warning dialog
             dialog = QtWidgets.QMessageBox()
diff --git a/src/ui/dialogs/medienadder.py b/src/ui/dialogs/medienadder.py
index ed5bd31..1f00c71 100644
--- a/src/ui/dialogs/medienadder.py
+++ b/src/ui/dialogs/medienadder.py
@@ -1,6 +1,6 @@
 from PyQt6 import QtCore, QtGui, QtWidgets
 
-from .dialog_sources.Ui_medianadder import Ui_Dialog
+from .dialog_sources.medianadder_ui import Ui_Dialog
 from src import Icon
 
 
diff --git a/src/ui/dialogs/parsed_titles.py b/src/ui/dialogs/parsed_titles.py
index be4f464..1142fe2 100644
--- a/src/ui/dialogs/parsed_titles.py
+++ b/src/ui/dialogs/parsed_titles.py
@@ -3,15 +3,14 @@ from PyQt6 import QtWidgets
 from src.backend import AutoAdder
 
 
-from .dialog_sources.Ui_parsed_titles import Ui_Form
+from .dialog_sources.parsed_titles_ui import Ui_Form
 import loguru
 import sys
 
 log = loguru.logger
 log.remove()
-log.add("application.log", rotation="1 week", retention="1 month")
-log.add(sys.stdout, level="INFO")
-
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
 class ParsedTitles(QtWidgets.QWidget, Ui_Form):
     def __init__(self, parent=None):
diff --git a/src/ui/dialogs/reminder.py b/src/ui/dialogs/reminder.py
index e6b79ca..4e096ff 100644
--- a/src/ui/dialogs/reminder.py
+++ b/src/ui/dialogs/reminder.py
@@ -1,6 +1,6 @@
 from PyQt6 import QtWidgets
 
-from .dialog_sources.Ui_reminder import Ui_Erinnerung as Ui_Dialog
+from .dialog_sources.reminder_ui import Ui_Erinnerung as Ui_Dialog
 from src import Icon
 import datetime as date
 
diff --git a/src/ui/dialogs/settings.py b/src/ui/dialogs/settings.py
index 55a4695..5211a1b 100644
--- a/src/ui/dialogs/settings.py
+++ b/src/ui/dialogs/settings.py
@@ -1,19 +1,15 @@
 from PyQt6 import QtCore, QtGui, QtWidgets
 from src import Icon, settings
-from .dialog_sources.Ui_settings import Ui_Dialog as _settings
+from .dialog_sources.settings_ui import Ui_Dialog as _settings
 from src.ui.widgets.iconLine import IconWidget
+import loguru
 import sys
-from loguru import logger as log
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
-log.add(
-    f"logs/settings.log",
-)
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
 
 
 base = """'
@@ -80,7 +76,7 @@ class Settings(QtWidgets.QDialog, _settings):
         self.toolBox.setItemIcon(2, Icon("mail").icon)
         self.toolBox.setItemIcon(3, Icon("icons").icon)
 
-        logger.info("Settings dialog opened, data loaded")
+        log.info("Settings dialog opened, data loaded")
 
     def load_config(self):
         self.db_name.setText(settings.database.name)
@@ -117,7 +113,7 @@ class Settings(QtWidgets.QDialog, _settings):
             self.vertical_icons.addWidget(icon_widget)
 
     def change_color(self, lineedit):
-        logger.debug("Changing color for {}", lineedit.text())
+        log.debug("Changing color for {}", lineedit.text())
         colorDialog = QtWidgets.QColorDialog()
         colorDialog.setSizePolicy()
         color = colorDialog.getColor()
@@ -191,7 +187,7 @@ class Settings(QtWidgets.QDialog, _settings):
             self.save_path.setText(file_dialog.selectedFiles()[0])
 
     def debug_mode(self):
-        logger.debug(self.editSignature.toHtml())
+        log.debug(self.editSignature.toHtml())
 
     def return_data(self):
         port = self.smtp_port.text()
diff --git a/src/ui/semesterapparat_ui.ui b/src/ui/semesterapparat_ui.ui
index c458296..d5a9c70 100644
--- a/src/ui/semesterapparat_ui.ui
+++ b/src/ui/semesterapparat_ui.ui
@@ -505,7 +505,7 @@
                  Qt::NoFocus
                 
                 
-                 Apparatsdetails
+                 SemesterApparatsdetails
                 
                 
                  Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
diff --git a/src/ui/semesterapparat_ui_ui.py b/src/ui/semesterapparat_ui_ui.py
index b4a1be2..4c0af77 100644
--- a/src/ui/semesterapparat_ui_ui.py
+++ b/src/ui/semesterapparat_ui_ui.py
@@ -1,6 +1,6 @@
 # Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\semesterapparat_ui.ui'
 #
-# Created by: PyQt6 UI code generator 6.8.0
+# Created by: PyQt6 UI code generator 6.9.0
 #
 # WARNING: Any manual changes made to this file will be lost when pyuic6 is
 # run again.  Do not edit this file unless you know what you are doing.
@@ -922,7 +922,7 @@ class Ui_MainWindow(object):
         item = self.tableWidget_apparat_media.horizontalHeaderItem(6)
         item.setText(_translate("MainWindow", "Link"))
         self.label.setText(_translate("MainWindow", "  Medienliste"))
-        self.app_group_box.setTitle(_translate("MainWindow", "Apparatsdetails"))
+        self.app_group_box.setTitle(_translate("MainWindow", "SemesterApparatsdetails"))
         item = self.document_list.horizontalHeaderItem(0)
         item.setText(_translate("MainWindow", "Dokumentname"))
         item = self.document_list.horizontalHeaderItem(1)
diff --git a/src/ui/userInterface.py b/src/ui/userInterface.py
index bc16eb5..6619a0d 100644
--- a/src/ui/userInterface.py
+++ b/src/ui/userInterface.py
@@ -32,15 +32,15 @@ from src.logic import (
 )
 from src.ui.dialogs import (
     popus_confirm,
-    medienadder_ui,
+    MedienAdder,
     About,
     ApparatExtendDialog,
     Mail_Dialog,
     Settings,
-    edit_bookdata_ui,
-    login_ui,
-    parsed_titles_ui,
-    reminder_ui,
+    BookDataUI,
+    LoginDialog,
+    ParsedTitles,
+    ReminderDialog,
     DocumentPrintDialog,
 )
 from src.ui.widgets import (
@@ -55,28 +55,27 @@ from src.ui.widgets import (
 )
 
 from datetime import datetime
-from loguru import logger as log
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", enqueue=True)
+import loguru
+
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
+
 log.add(
     f"logs/{datetime.now().strftime('%Y-%m-%d')}.log",
     rotation="1 day",
-    compression="zip",
+    retention="1 month",
 )
 
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
-
-
 valid_input = (0, 0, 0, 0, 0, 0)
 
 
 class Ui(Ui_Semesterapparat):
     # use the Ui_MainWindow class from mainwindow.py
     def __init__(self, MainWindow, username: str) -> None:  # type:ignore
-        logger.info("Starting Semesterapparatsmanagement")
+        log.info("Starting Semesterapparatsmanagement")
         super().__init__()
         self.active_user = username
         self.setupUi(MainWindow)  # type:ignore
@@ -116,7 +115,6 @@ class Ui(Ui_Semesterapparat):
         self.tableWidget_apparate.horizontalHeader().setSectionResizeMode(  # type:ignore
             QtWidgets.QHeaderView.ResizeMode.Stretch
         )
-        self.tableWidget_apparate.setSortingEnabled(True)
         self.saveandcreate.hide()
 
         # Actions
@@ -142,7 +140,7 @@ class Ui(Ui_Semesterapparat):
         self.prof_tel_nr.setValidator(
             QtGui.QRegularExpressionValidator(QtCore.QRegularExpression(r"^\d{3,14}"))
         )
-        # #logger.debug(self.prof_tel_nr.maxLength())
+        # #log.debug(self.prof_tel_nr.maxLength())
         self.app_fach.setValidator(  # validator to allow typing in the app_fach field
             QtGui.QRegularExpressionValidator(
                 QtCore.QRegularExpression(r"[a-zA-Z0-9\s\W]+")
@@ -160,7 +158,7 @@ class Ui(Ui_Semesterapparat):
         )
         self.tableWidget_apparate.doubleClicked.connect(self.load_app_data)  # type:ignore
 
-        # #logger.debug(f"user:{self.active_user}")
+        # #log.debug(f"user:{self.active_user}")
         userrole = self.db.getRole(self.active_user)
         # hide admin interface when non-admin is logged in
         if userrole == "admin":
@@ -239,7 +237,7 @@ class Ui(Ui_Semesterapparat):
         self.admin_action.setTitle("")
 
         # Create instances to be used by the threads in the application
-        self.bookGrabber = []
+        self.bookGrabber: list[QThread] = []
         self.availChecker = None
         self.mail_thread = None
         self.autoGrabber = None
@@ -260,7 +258,7 @@ class Ui(Ui_Semesterapparat):
         self.valid_check_semester.clicked.connect(self.display_valid_semester)  # type:ignore
 
     def create_doc(self):
-        logger.debug("Creating document")
+        log.debug("Creating document")
         # open DocumentPrintDialog
         dialog = DocumentPrintDialog(self.MainWindow)
         dialog.show()
@@ -332,7 +330,7 @@ class Ui(Ui_Semesterapparat):
         self.app_fach.addItems([subject[1] for subject in self.db.getSubjects()])
 
     def open_documentation(self):
-        logger.info("Opening Documentation")
+        log.info("Opening Documentation")
         if not self.docu.isRunning():
             self.docu.start()
         webbrowser.open("http://localhost:8000")
@@ -357,7 +355,7 @@ class Ui(Ui_Semesterapparat):
             statistics.updateCalendar.connect(self.update_calendar)
             stats_layout.addWidget(statistics)
 
-            # #logger.debug("searchpage")
+            # #log.debug("searchpage")
         if self.tabWidget.currentIndex() == 0:  # Apparate
             # clear all entries from the table
             self.tableWidget_apparate.setRowCount(0)
@@ -375,7 +373,7 @@ class Ui(Ui_Semesterapparat):
                     widget.deleteLater()
 
             elsa_layout.addWidget(ElsaDialog())
-            # logger.debug("added")
+            # log.debug("added")
             pass
 
     def generateSemester(self, today=False):
@@ -418,9 +416,9 @@ class Ui(Ui_Semesterapparat):
         self.prof_mail.setText(appdata.prof.mail)
         self.prof_tel_nr.setText(appdata.prof.telnr)
         self.app_name.setText(appdata.apparat.name)
-        # #logger.debug("changing dropdown app_fach from '' to ", appdata.app_fach)
+        # #log.debug("changing dropdown app_fach from '' to ", appdata.app_fach)
         self.app_fach.setCurrentText(appdata.apparat.subject)
-        # #logger.debug("changed dropdown app_fach to ", self.app_fach.currentText())
+        # #log.debug("changed dropdown app_fach to ", self.app_fach.currentText())
         self.sem_year.setText(appdata.apparat.get_semester.split(" ")[1])
         match appdata.apparat.get_semester.split(" ")[0]:
             case "SoSe":
@@ -485,7 +483,7 @@ class Ui(Ui_Semesterapparat):
         return popup.result()
 
     def thread_check(self):
-        # #logger.debug("Thread started")
+        # #log.debug("Thread started")
         self.prof_mail.textChanged.connect(self.validate_prof_mail)
         self.drpdwn_prof_name.editTextChanged.connect(self.validate_prof_name)
         self.prof_tel_nr.textChanged.connect(self.validate_prof_tel)
@@ -596,7 +594,7 @@ class Ui(Ui_Semesterapparat):
             return
         selected_prof = self.drpdwn_prof_name.currentText()
         data = self.db.getProfData(selected_prof)
-        # logger.debug(data)
+        # log.debug(data)
         prof_title = data.title
         if prof_title == "None":
             prof_title = "Kein Titel"
@@ -700,20 +698,20 @@ class Ui(Ui_Semesterapparat):
 
     def update_progress_label(self, curr: int, total: int):
         text = f"Medium {curr}/{total}"
-        logger.info(text)
+        log.info(text)
         self.progress_label.setText(text)
         # update tableWidget_apparat_media
         self.update_app_media_list()
 
     def hide_progress_label(self):
-        logger.info("Finished adding media, hiding progress label")
+        log.info("Finished adding media, hiding progress label")
         self.progress_label.hide()
         self.progress_label.setText("Bitte warten...")
         self.line_2.hide()
         self.label_info.hide()
 
     def btn_add_medium(self):
-        media = medienadder_ui()
+        media = MedienAdder()
         media.exec()
         mode = media.mode
         data = media.data
@@ -733,7 +731,7 @@ class Ui(Ui_Semesterapparat):
 
             app_id = self.active_apparat
             prof_id = self.db.getProfId(self.profdata)
-            logger.debug(prof_id)
+            log.debug(prof_id)
             # check if app_id is in database
             if self.db.checkApparatExistsById(app_id) is False:
                 # create apparat
@@ -756,7 +754,7 @@ class Ui(Ui_Semesterapparat):
 
             bookGrabber.start()
             while bookGrabber.isRunning():
-                # #logger.debug("waiting for thread to finish")
+                # #log.debug("waiting for thread to finish")
                 QtWidgets.QApplication.processEvents()
 
             # self.__clear_fields()
@@ -802,7 +800,7 @@ class Ui(Ui_Semesterapparat):
 
         # thread = QThread()
         appnumber = self.active_apparat
-        # #logger.debug(links)
+        # #log.debug(links)
         self.availChecker = AvailChecker(links, appnumber, books=books)
         # availcheck.moveToThread(thread)
         # availcheck.finished.connect(thread.quit)
@@ -851,7 +849,7 @@ class Ui(Ui_Semesterapparat):
             app_id, prof_id, deleted
         )
 
-        # # #logger.debug(books)
+        # # #log.debug(books)
         # take the dataclass from the tuple
         # booklist:list[BookData]=[book[0] for book in books]
         self.tableWidget_apparat_media.setRowCount(0)
@@ -860,7 +858,7 @@ class Ui(Ui_Semesterapparat):
             book_data = book["bookdata"]
             availability = book["available"]
             # bd = BookData().from_string(book)
-            # # #logger.debug(bd, type(bd))
+            # # #log.debug(bd, type(bd))
             # create a new row below the last one
             self.tableWidget_apparat_media.insertRow(
                 self.tableWidget_apparat_media.rowCount()
@@ -954,11 +952,11 @@ class Ui(Ui_Semesterapparat):
             self.drpdwn_prof_name.addItem(prof)
 
     def add_document(self):
-        # #logger.debug("Add document")
+        # #log.debug("Add document")
         picker = FilePicker()
         files = picker.pick_files()
         for file in files:
-            # #logger.debug(file)
+            # #log.debug(file)
             filename = file.split("/")[-1]
             filetype = filename.split(".")[-1]
             self.document_list.insertRow(0)
@@ -1008,7 +1006,7 @@ class Ui(Ui_Semesterapparat):
 
         def __open_dialog(signatures: list[str]):
             dialog = QtWidgets.QDialog()
-            frame = parsed_titles_ui()
+            frame = ParsedTitles()
             frame.setupUi(dialog)
             dialog.show()
             frame.signatures = signatures
@@ -1030,7 +1028,7 @@ class Ui(Ui_Semesterapparat):
         else:
             # if file is selected, check for books in the file
             if self.document_list.currentRow() != -1:
-                # #logger.debug("File selected")
+                # #log.debug("File selected")
                 file = self.document_list.item(
                     self.document_list.currentRow(), 3
                 ).text()
@@ -1084,7 +1082,7 @@ class Ui(Ui_Semesterapparat):
                             bookdata=book, app_id=app_id, prof_id=prof_id
                         )
                 self.update_app_media_list()
-                # #logger.debug(len(signatures))
+                # #log.debug(len(signatures))
 
     def extract_document_data(self) -> Union[list[str], SemapDocument]:
         file_type = self.document_list.item(self.document_list.currentRow(), 1).text()
@@ -1093,7 +1091,7 @@ class Ui(Ui_Semesterapparat):
         ).text()
         file_name = self.document_list.item(self.document_list.currentRow(), 0).text()
         file = file_location
-        logger.info("File selected: {}, {}", file_name, file_location)
+        log.info("File selected: {}, {}", file_name, file_location)
         if file_location == "Database":
             # create warning, then return
             self.db.recreateFile(file_name, self.active_apparat, filetype=file_type)
@@ -1107,8 +1105,8 @@ class Ui(Ui_Semesterapparat):
             return signatures
         if file_type == "docx":
             data = word_to_semap(file)
-            logger.info("Converted data from semap file")
-            logger.debug("Got the data: {}", data)
+            log.info("Converted data from semap file")
+            log.debug("Got the data: {}", data)
 
             return data
 
@@ -1132,17 +1130,17 @@ class Ui(Ui_Semesterapparat):
         for runner in self.bookGrabber:
             if not runner.isRunning():
                 runner.deleteLater()
-        # #logger.debug("Checking file")
+        # #log.debug("Checking file")
         # get active app_id and prof_id
         self.tableWidget_apparate.setEnabled(False)
         self.tableWidget_apparate.setToolTip(
             "Bitte warten, bis alle Medien hinzugefügt wurden"
         )
         app_id = self.active_apparat
-        logger.debug(self.profdata)
+        log.debug(self.profdata)
         prof_id = self.db.getProfId(self.profdata)
 
-        logger.debug("Prof id: {}", prof_id)
+        log.debug("Prof id: {}", prof_id)
         # check if apparat in database
         if prof_id is None:
             prof = Prof(
@@ -1155,28 +1153,28 @@ class Ui(Ui_Semesterapparat):
             self.db.createProf(prof)
         # if app_id not in database, create apparat
         if not self.db.checkApparatExistsById(app_id):
-            logger.info("Apparat does not exist, creating new apparat")
+            log.info("Apparat does not exist, creating new apparat")
             # create apparat
-            # #logger.debug("Creating apparat")
+            # #log.debug("Creating apparat")
             if not self.btn_save_apparat(False):
                 return
 
         if self.document_list.rowCount() == 0:
-            logger.info("No file selected")
+            log.info("No file selected")
             self.tableWidget_apparate.setEnabled(True)
             self.tableWidget_apparate.setToolTip("")
             return
         else:
             # if file is selected, check for books in the file
-            # #logger.debug("File selected")
+            # #log.debug("File selected")
 
             if prof_id is None:
                 prof_id = self.db.getProfId(self.profdata)
 
-                # logger.debug("Prof ID is None", prof_id)
+                # log.debug("Prof ID is None", prof_id)
             document = self.extract_document_data()
             if document is None:
-                logger.error("Document is None")
+                log.error("Document is None")
             elif isinstance(document, SemapDocument):
                 signatures = document.signatures
             else:
@@ -1287,7 +1285,7 @@ class Ui(Ui_Semesterapparat):
                 pid=appd.prof.fullname,
             )
         if clear_fields:
-            # #logger.debug("clearing fields")
+            # #log.debug("clearing fields")
             self.__clear_fields()
         return True
 
@@ -1346,10 +1344,10 @@ class Ui(Ui_Semesterapparat):
 
         for apparat in self.apparats:
             self.insert_apparat_into_table(apparat)
-        logger.info("Inserted {} apparats into table".format(len(self.apparats)))
+        log.info("Inserted {} apparats into table".format(len(self.apparats)))
 
     def insert_apparat_into_table(self, apparat):
-        # logger.debug(apparat)
+        # log.debug(apparat)
         def __dauer_check(apparat):
             return "Ja" if apparat[7] == 1 else "Nein"
 
@@ -1398,7 +1396,7 @@ class Ui(Ui_Semesterapparat):
             return
         app_id = self.tableWidget_apparate.item(row, 0).text()
         pid = self.db.getProfIDByApparat(app_id)
-        logger.debug(app_id, pid)
+        log.debug(app_id, pid)
         delete_action.triggered.connect(lambda: self.delete_apparat(pos))
         # pass pos to contact_prof
         contact_action.triggered.connect(
@@ -1407,14 +1405,14 @@ class Ui(Ui_Semesterapparat):
         menu.exec(self.tableWidget_apparate.mapToGlobal(position))
 
     def reminder(self):
-        logger.info("Opening reminder dialog")
-        reminder = reminder_ui()
+        log.info("Opening reminder dialog")
+        reminder = ReminderDialog()
         reminder.exec()
         tableposition = self.tableWidget_apparate.currentRow()
         appnr = self.tableWidget_apparate.item(tableposition, 0).text()
         if reminder.result() == QtWidgets.QDialog.DialogCode.Accepted:
             data = reminder.return_message()
-            # #logger.debug(data)
+            # #log.debug(data)
             self.db.addMessage(
                 data,
                 self.active_user,
@@ -1423,18 +1421,18 @@ class Ui(Ui_Semesterapparat):
             self.update_calendar(data)
             # self.db.update_bookdata(data, book_id)
             # self.db.update_bookdata(data)
-            logger.info("committed message to database")
+            log.info("committed message to database")
             # self.update_app_media_list()
 
     def get_reminders(self):
         messages = self.db.getAllMessages()
-        logger.info(f"Got {len(messages)} messages from database")
+        log.info(f"Got {len(messages)} messages from database")
         self.calendarWidget.setMessages(messages)
         self.calendarWidget.updateCells()
 
     def open_reminder(self):
         selected_date = self.calendarWidget.selectedDate().toString("yyyy-MM-dd")
-        # # #logger.debug(selected_date)
+        # # #log.debug(selected_date)
         messages = self.db.getMessages(selected_date)
         if messages == []:
             return
@@ -1445,13 +1443,13 @@ class Ui(Ui_Semesterapparat):
         dialog.repaintSignal.connect(lambda: self.calendarWidget.reload(selected_date))
 
     def open_settings(self):
-        # logger.debug(settings.dict())
+        # log.debug(settings.dict())
         settingsUI = Settings(self.active_user)
         settingsUI.exec()
 
         if settingsUI.result() == QtWidgets.QDialog.DialogCode.Accepted:
             settingsUI.save()
-            # logger.debug(settings.dict())
+            # log.debug(settings.dict())
 
     #            self.reload()
 
@@ -1470,6 +1468,7 @@ class Ui(Ui_Semesterapparat):
 
         delete_action = QtGui.QAction("Löschen")
         edit_action = QtGui.QAction("Bearbeiten")
+        update_data_action = QtGui.QAction("Daten aktualisieren")
         apparat_add_action = QtGui.QAction("Zum Apparat hinzufügen")
         apparat_move_action = QtGui.QAction("In Apparat verschieben")
         apparat_copy_action = QtGui.QAction("In Apparat kopieren")
@@ -1479,7 +1478,7 @@ class Ui(Ui_Semesterapparat):
         apparatmenu.addActions(
             [apparat_add_action, apparat_copy_action, apparat_move_action]
         )
-        generalmenu.addActions([edit_action, delete_action])
+        generalmenu.addActions([edit_action, delete_action, update_data_action])
         # disable apparat_add_action
         apparat_add_action.setEnabled(False)
         delete_action.triggered.connect(self.delete_medium)
@@ -1487,8 +1486,13 @@ class Ui(Ui_Semesterapparat):
         apparat_add_action.triggered.connect(self.add_to_apparat)
         apparat_copy_action.triggered.connect(self.copy_to_apparat)
         apparat_move_action.triggered.connect(self.move_to_apparat)
+        update_data_action.triggered.connect(self.update_data)
         menu.exec(self.tableWidget_apparat_media.mapToGlobal(position))
 
+    def update_data(self):
+        # TODO: use link in table, parse data and if needed, update location / signature
+        pass
+
     def copy_to_apparat(self):
         selected_rows = self.tableWidget_apparat_media.selectionModel().selectedRows()
         signatures = []
@@ -1577,7 +1581,7 @@ class Ui(Ui_Semesterapparat):
             signature=signature,
             prof_id=self.db.getProfId(self.profdata),
         )
-        # logger.debug(medium.adis_idn, medium.signature)
+        # log.debug(medium.adis_idn, medium.signature)
 
     def edit_medium(self):
         book = self.tableWidget_apparat_media.item(
@@ -1595,7 +1599,7 @@ class Ui(Ui_Semesterapparat):
             book,
         )
         widget = QtWidgets.QDialog()
-        bookedit = edit_bookdata_ui()
+        bookedit = BookDataUI()
         bookedit.setupUi(widget)
         widget.setWindowIcon(Icon("settings").icon)
         # change title of dialog
@@ -1604,10 +1608,10 @@ class Ui(Ui_Semesterapparat):
         widget.exec()
         if widget.result() == QtWidgets.QDialog.DialogCode.Accepted:
             data = bookedit.get_data()
-            # #logger.debug(data)
+            # #log.debug(data)
             self.db.updateBookdata(bookdata=data, book_id=book_id)
             # self.db.update_bookdata(data)
-            # #logger.debug("accepted")
+            # #log.debug("accepted")
             self.update_app_media_list()
         else:
             return
@@ -1631,7 +1635,7 @@ class Ui(Ui_Semesterapparat):
             )
             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, title="Löschen?")
-            # #logger.debug(state)
+            # #log.debug(state)
             if state == 1:
                 self.db.deleteBook(book_id)
                 self.update_app_media_list()
@@ -1643,7 +1647,7 @@ class Ui(Ui_Semesterapparat):
             for r in ranges:
                 for row in range(r.topRow(), r.bottomRow() + 1):
                     rows.append(row)
-            # #logger.debug(rows)
+            # #log.debug(rows)
             message = f"Sollen die {len(rows)} Medien wirklich gelöscht werden?"
             state = self.confirm_popup(message, title="Löschen?")
             if state == 1:
@@ -1663,12 +1667,12 @@ class Ui(Ui_Semesterapparat):
         # return data from dialog if ok is pressed
         if framework.result() == QtWidgets.QDialog.DialogCode.Accepted:
             data = framework.get_data()
-            # #logger.debug(data)
+            # #log.debug(data)
             # return data
             selected_apparat_id = self.tableWidget_apparate.item(
                 self.tableWidget_apparate.currentRow(), 0
             ).text()
-            # #logger.debug(selected_apparat_id)
+            # #log.debug(selected_apparat_id)
 
             self.db.setNewSemesterDate(
                 selected_apparat_id, data["semester"], dauerapp=data["dauerapp"]
@@ -1679,7 +1683,7 @@ class Ui(Ui_Semesterapparat):
             return
 
     def __contact_dialog(self, apparat, location: tuple | str, mail=None, pid=""):
-        logger.debug(
+        log.debug(
             "Got these values apparat: {}, location: {}, mail: {}, pid: {}".format(
                 apparat, location, mail, pid
             )
@@ -1722,8 +1726,8 @@ class Ui(Ui_Semesterapparat):
         self.mail_thread.show()
 
     def contact_prof(self, apparat="", location="", mail="", pid=""):
-        logger.debug(apparat)
-        logger.debug(location)
+        log.debug(apparat)
+        log.debug(location)
         if self.active_apparat == "":
             if apparat is False:
                 self.confirm_popup(
@@ -1739,10 +1743,10 @@ class Ui(Ui_Semesterapparat):
         ).text()
         message = f"Soll der Apparat {selected_apparat_id} wirklich gelöscht werden?"
         state = self.confirm_popup(message, title="Löschen?")
-        # #logger.debug(state)
-        logger.info("Result state: {}", state)
+        # #log.debug(state)
+        log.info("Result state: {}", state)
         if state == 1:
-            logger.debug("Deleting apparat {}", selected_apparat_id)
+            log.debug("Deleting apparat {}", selected_apparat_id)
             pid = self.db.getProfIDByApparat(selected_apparat_id)
             self.db.deleteApparat(selected_apparat_id, Semester().value)
             # delete the corresponding entry from self.apparats
@@ -1751,7 +1755,7 @@ class Ui(Ui_Semesterapparat):
                     self.apparats.remove(apparat)
                     break
             self.old_apparats = self.apparats
-            # #logger.debug(self.apparats)
+            # #log.debug(self.apparats)
             # remove the row from the table
             self.tableWidget_apparate.removeRow(self.tableWidget_apparate.currentRow())
             # send mail to prof
@@ -1759,24 +1763,24 @@ class Ui(Ui_Semesterapparat):
 
 
 def launch_gui():
-    # #logger.debug("trying to login")
-    # #logger.debug("checking if database available")
+    # #log.debug("trying to login")
+    # #log.debug("checking if database available")
 
-    logger.info("Starting login dialog")
+    log.info("Starting login dialog")
     app = QtWidgets.QApplication(sys.argv)
     login_dialog = QtWidgets.QDialog()
-    ui = login_ui()
+    ui = LoginDialog()
     ui.setupUi(login_dialog)
     login_dialog.exec()  # This will block until the dialog is closed
 
     if ui.lresult == 1:
         # if login is successful, open main window
         # show login dialog
-        # #logger.debug(ui.lusername)
+        # #log.debug(ui.lusername)
         MainWindow = QtWidgets.QMainWindow()
         aui = Ui(MainWindow, username=ui.lusername)
 
-        # #logger.debug(aui.active_user)
+        # #log.debug(aui.active_user)
         MainWindow.show()
         # atexit.register()
         atexit.register(tempdelete)
@@ -1793,7 +1797,7 @@ def launch_gui():
 
 
 if __name__ == "__main__":
-    # #logger.debug("This is the main window")
+    # #log.debug("This is the main window")
     # app = QtWidgets.QApplication(sys.argv)
     # window = MainWindow()
     # app.exec()
diff --git a/src/ui/widgets/MessageCalendar.py b/src/ui/widgets/MessageCalendar.py
index a659440..48d93eb 100644
--- a/src/ui/widgets/MessageCalendar.py
+++ b/src/ui/widgets/MessageCalendar.py
@@ -3,17 +3,15 @@ from PyQt6.QtCore import QDate
 from PyQt6.QtGui import QColor, QPen
 from src.backend import Database
 import darkdetect
+import loguru
 import sys
-from loguru import logger as log
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
 
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
-
 color = "#ddfb00" if darkdetect.isDark() else "#2204ff"
 pen = QPen(QColor(color))
 pen.setWidth(5)
@@ -31,7 +29,7 @@ class MessageCalendar(QtWidgets.QCalendarWidget):
     def getMessages(self):
         # Get the messages from the database
         messages = Database().getAllMessages()
-        logger.debug("Got {} messages", len(messages))
+        log.debug("Got {} messages", len(messages))
         self.setMessages(messages)
 
     def deleteMessage(self, id):
diff --git a/src/ui/widgets/admin_edit_prof.py b/src/ui/widgets/admin_edit_prof.py
index 5fe42fc..dfb9195 100644
--- a/src/ui/widgets/admin_edit_prof.py
+++ b/src/ui/widgets/admin_edit_prof.py
@@ -3,15 +3,14 @@ from PyQt6 import QtWidgets
 
 from src.logic import Prof
 from src.backend import Database
+import loguru
 import sys
-from loguru import logger as log
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
 
 
 class EditProf(QtWidgets.QDialog, Ui_Dialog):
@@ -69,7 +68,7 @@ class EditProf(QtWidgets.QDialog, Ui_Dialog):
         else:
             self.faculty_member_old_telnr.setText(data.telnr)
             self.faculty_member_oldmail.setText(data.mail)
-            logger.debug(data)
+            log.debug(data)
             (
                 self.edit_faculty_member_title.setText(data.title)
                 if data.title is not None
@@ -93,7 +92,7 @@ class EditProf(QtWidgets.QDialog, Ui_Dialog):
         olddata = self.db.getProfByName(
             self.edit_faculty_member_select_member.currentText()
         )
-        logger.debug(olddata)
+        log.debug(olddata)
         data = olddata
         oldlname = data.lastname
         oldfname = data.firstname
diff --git a/src/ui/widgets/elsa_main.py b/src/ui/widgets/elsa_main.py
index ec4f637..0a0b5a4 100644
--- a/src/ui/widgets/elsa_main.py
+++ b/src/ui/widgets/elsa_main.py
@@ -9,15 +9,14 @@ from src.logic import elsa_word_to_csv, Prof
 from src.ui.dialogs import ElsaAddEntry, popus_confirm
 from src.ui.widgets import FilePicker, DataGraph
 from src.backend import recreateElsaFile
+import loguru
 import sys
-from loguru import logger as log
 
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
-log.add("logs/elsa_main.log", enqueue=True)
-logger.add(sys.stdout)
 
 
 class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
@@ -93,7 +92,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
         self.newProf_title.textChanged.connect(self.checkProfData)
 
         self.loadFrame()
-        logger.info("Elsa Dialog loaded")
+        log.info("Elsa Dialog loaded")
         # self.show()
 
     def checkProfData(self):
@@ -237,7 +236,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
             fullname=f"{prof.split(', ')[0]} {prof.split(', ')[1]}",
         )
         prof_id = self.db.getProfId(profdata)
-        logger.debug(f"ProfData: {profdata}, id:{prof_id}")
+        log.debug(f"ProfData: {profdata}, id:{prof_id}")
 
         if prof_id is None:
             self.db.createProf(profdata)
@@ -263,12 +262,12 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
                 files,
                 elsa_id,
             )
-            logger.info("Stored {} files in the database", len(files))
+            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)
-        logger.info("Saved apparat to database, id {}", elsa_id)
+        log.info("Saved apparat to database, id {}", elsa_id)
 
     def refresh_elsa_table(self):
         self.elsa_table.setRowCount(0)
@@ -288,13 +287,13 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
 
     def open_elsa(self):
         prof = self.elsa_table.item(self.elsa_table.currentRow(), 0).text()
-        logger.info("prof", prof)
+        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():
-            logger.debug("Same prof, stopping")
+            log.debug("Same prof, stopping")
             return
         self.create_frame_elsa.setEnabled(True)
         self.dokument_list_elsa.setRowCount(0)
@@ -314,7 +313,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
         self.elsa_date.setText(date)
         self.elsa_semester.setText(semester)
         self.elsa_prof.setCurrentText(prof)
-        logger.info("Elsa ID is {}", elsa_id)
+        log.info("Elsa ID is {}", elsa_id)
         if elsa_id is None:
             return
         documents = self.db.getElsaFiles(elsa_id)
@@ -411,7 +410,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
                 self.elsa_semester.text(),
                 self.elsa_date.text(),
             )
-            logger.debug(
+            log.debug(
                 f"elsa_id: {elsa_id}, prof: {self.elsa_prof.currentText()}, semester: {self.elsa_semester.text()}, date: {self.elsa_date.text()}"
             )
             for row in data:
@@ -445,7 +444,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
         try:
             self.elsa_statistics.removeTab(1)
         except:
-            logger.debug("No tab to remove")
+            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)
@@ -469,7 +468,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
             data=self.graph_data,
             label="Anzahl der Apparate",
         )
-        logger.debug(self.graph_data)
+        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)
@@ -483,7 +482,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
 
 
 def launch():
-    logger.debug("Launching Elsa Dialog")
+    log.debug("Launching Elsa Dialog")
     app = QtWidgets.QApplication([])
     window = ElsaDialog()
     window.show()
diff --git a/src/ui/widgets/graph.py b/src/ui/widgets/graph.py
index 4f8987c..a7a389f 100644
--- a/src/ui/widgets/graph.py
+++ b/src/ui/widgets/graph.py
@@ -3,18 +3,13 @@ from typing import Union
 
 import pyqtgraph as pg
 from PyQt6 import QtWidgets
+import loguru
 import sys
-from loguru import logger as log
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
-log.add(
-    "logs/graph.log",
-)
-
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
 
 def mergedicts(d1, d2):
@@ -43,7 +38,7 @@ class DataGraph(QtWidgets.QWidget):
         label=None,
     ):
         super().__init__()
-        logger.debug(
+        log.debug(
             "Initialized with options: {}, {}, {}, {}".format(
                 title, data, generateMissing, label
             )
diff --git a/src/ui/widgets/iconLine.py b/src/ui/widgets/iconLine.py
index 0399abb..d4f1478 100644
--- a/src/ui/widgets/iconLine.py
+++ b/src/ui/widgets/iconLine.py
@@ -6,7 +6,7 @@ from loguru import logger as log
 
 logger = log
 logger.remove()
-logger.add("logs/application.log", rotation="1 week", enqueue=True)
+logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
 
 
 # logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
@@ -29,9 +29,12 @@ class IconWidget(QtWidgets.QWidget, Ui_Dialog):
             self.icon_filename_line.setText(
                 file_dialog.selectedFiles()[0].split("/")[-1]
             )
-        logger.debug(
-            "Icon changed to: {}", file_dialog.selectedFiles()[0].split("/")[-1]
-        )
+        try:
+            log.debug(
+                "Icon changed to: {}", file_dialog.selectedFiles()[0].split("/")[-1]
+            )
+        except IndexError:
+            log.debug("No file selected")
 
     def return_data(self):
         return self.icon_name_settings.text(), self.icon_filename_line.text()
diff --git a/src/ui/widgets/searchPage.py b/src/ui/widgets/searchPage.py
index fe0fb68..87fe6ea 100644
--- a/src/ui/widgets/searchPage.py
+++ b/src/ui/widgets/searchPage.py
@@ -4,20 +4,18 @@ from PyQt6.QtCore import pyqtSignal
 from src.backend import Database, Semester
 
 from src.logic import custom_sort, Prof, sort_semesters_list
-from src.ui.dialogs import Mail_Dialog, ApparatExtendDialog, reminder_ui
+from src.ui.dialogs import Mail_Dialog, ApparatExtendDialog, ReminderDialog
 from src.ui.widgets import DataGraph, StatusWidget
 
 from natsort import natsorted
+import loguru
 import sys
-from loguru import logger as log
 
-logger = log
-logger.remove()
-logger.add("logs/application.log", rotation="1 week", retention="1 month", enqueue=True)
-log.add("logs/searchPage.log", enqueue=True)
+log = loguru.logger
+log.remove()
+log.add(sys.stdout)
+log.add("logs/application.log", rotation="1 MB", retention="10 days")
 
-# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
-logger.add(sys.stdout)
 
 
 class MyComboBox(QtWidgets.QComboBox):
@@ -32,7 +30,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
     updateCalendar = pyqtSignal(int, list)
 
     def __init__(self):
-        logger.info("SearchStatisticPage started")
+        log.info("SearchStatisticPage started")
         super().__init__()
         self.setupUi(self)
         self.book_search_result.horizontalHeader().setSectionResizeMode(
@@ -111,7 +109,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
         extend.exec()
         if extend.result() == QtWidgets.QDialog.DialogCode.Accepted:
             data = extend.get_data()
-            logger.debug(data)
+            log.debug(data)
             app_name = self.tableWidget.item(self.tableWidget.currentRow(), 1).text()
             app_id = self.db.getApparatId(app_name)
             self.db.setNewSemesterDate(app_id, data["semester"], data["dauerapp"])
@@ -120,8 +118,8 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
             self.refreshSignal.emit()
 
     def reminder(self):
-        logger.info("Opening reminder dialog")
-        reminder = reminder_ui()
+        log.info("Opening reminder dialog")
+        reminder = ReminderDialog()
         reminder.exec()
         tableposition = self.tableWidget.currentRow()
         appnr = self.tableWidget.item(tableposition, 2).text()
@@ -134,7 +132,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
                 appnr,
             )
             self.updateCalendar.emit(data)
-            logger.info("committed message to database")
+            log.info("committed message to database")
 
     def tabW2_changed(self):
         if self.tabWidget_2.currentIndex() == 0:
@@ -151,12 +149,12 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
             "title": title if title != "" else None,
         }
         params = {key: value for key, value in params.items() if value is not None}
-        logger.debug(params)
+        log.debug(params)
         retdata = self.db.searchBook(params)
         if retdata is None:
             return
         for book in retdata:
-            logger.debug(book)
+            log.debug(book)
             self.book_search_result.insertRow(0)
             self.book_search_result.setItem(
                 0, 0, QtWidgets.QTableWidgetItem(book[0].title)
@@ -188,7 +186,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
 
                 selected_apparats.append(data)
         # delete all selected apparats
-        logger.debug(selected_apparats)
+        log.debug(selected_apparats)
         dialogs = []
         for i in selected_apparats:
             app_id = i["app_id"]
@@ -248,7 +246,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
             self.box_dauerapp.setEnabled(True)
 
     def populate_tab(self, table_or_graph=0):
-        logger.info("populate_tab started")
+        log.info("populate_tab started")
         # add default values to the dropdowns
         self.box_appnrs.clear()
         self.box_appnrs.addItem("")
@@ -315,7 +313,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
         # place the graph into tabWidget_3
         self.tabWidget_3.addTab(graph, "Graph")
         self.tabWidget_3.setCurrentIndex(table_or_graph)
-        logger.info("populate_tab finished")
+        log.info("populate_tab finished")
 
     def delete_selected_apparats(self):
         # get all selected apparats
@@ -327,7 +325,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
                 selected_apparat_rows.append(i)
         # delete all selected apparats
         # # #print(selected_apparats)
-        logger.info(f"Deleting apparats: {selected_apparats}")
+        log.info(f"Deleting apparats: {selected_apparats}")
         for apparat in selected_apparats:
             self.db.deleteApparat(apparat, self.semester)
         for row in selected_apparat_rows:
@@ -400,7 +398,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
                 sem = Semester().from_string(
                     entry[8] if entry[8] is not None else entry[5]
                 )
-                logger.info(f"Semester: {sem}")
+                log.info(f"Semester: {sem}")
                 if sem.isPastSemester(Semester()):
                     data.append(entry)
             else:
diff --git a/src/ui/widgets/widget_sources/search_statistic_page.ui b/src/ui/widgets/widget_sources/search_statistic_page.ui
index e1a2122..5356983 100644
--- a/src/ui/widgets/widget_sources/search_statistic_page.ui
+++ b/src/ui/widgets/widget_sources/search_statistic_page.ui
@@ -209,17 +209,7 @@
       
       
        
-        
-         
-          
-           
-            Signatur
-           
-           
-            seach_by_signature
-           
-          
-         
+        
          
           
            
@@ -240,26 +230,6 @@
            
           
          
-         
-          
-           
-            Suchen
-           
-          
-         
-         
-          
-           
-            Qt::ClickFocus
-           
-           
-            Trunkierung mit * am Ende unterstützt
-           
-           
-            true
-           
-          
-         
          
           
            
@@ -273,6 +243,29 @@
            
           
          
+         
+          
+           
+            Signatur
+           
+           
+            search_by_signature
+           
+          
+         
+         
+          
+           
+            Qt::ClickFocus
+           
+           
+            Trunkierung mit * am Ende unterstützt
+           
+           
+            true
+           
+          
+         
         
        
        
@@ -582,9 +575,8 @@
   box_dauerapp
   btn_search
   book_search_result
-  seach_by_signature
+  search_by_signature
   search_by_title
-  book_search
  
  
  
diff --git a/src/ui/widgets/widget_sources/search_statistic_page_ui.py b/src/ui/widgets/widget_sources/search_statistic_page_ui.py
index 5a187e6..210d580 100644
--- a/src/ui/widgets/widget_sources/search_statistic_page_ui.py
+++ b/src/ui/widgets/widget_sources/search_statistic_page_ui.py
@@ -102,9 +102,6 @@ class Ui_Dialog(object):
         self.horizontalLayout_3.setObjectName("horizontalLayout_3")
         self.gridLayout = QtWidgets.QGridLayout()
         self.gridLayout.setObjectName("gridLayout")
-        self.label_25 = QtWidgets.QLabel(parent=self.tab_4)
-        self.label_25.setObjectName("label_25")
-        self.gridLayout.addWidget(self.label_25, 0, 0, 1, 1)
         self.label_26 = QtWidgets.QLabel(parent=self.tab_4)
         self.label_26.setObjectName("label_26")
         self.gridLayout.addWidget(self.label_26, 1, 0, 1, 1)
@@ -113,20 +110,16 @@ class Ui_Dialog(object):
         self.search_by_title.setClearButtonEnabled(True)
         self.search_by_title.setObjectName("search_by_title")
         self.gridLayout.addWidget(self.search_by_title, 1, 1, 1, 1)
-        self.book_search = QtWidgets.QPushButton(parent=self.tab_4)
-        self.book_search.setObjectName("book_search")
-        self.gridLayout.addWidget(self.book_search, 3, 0, 1, 1)
-        self.seach_by_signature = QtWidgets.QLineEdit(parent=self.tab_4)
-        self.seach_by_signature.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus)
-        self.seach_by_signature.setClearButtonEnabled(True)
-        self.seach_by_signature.setObjectName("seach_by_signature")
-        self.gridLayout.addWidget(self.seach_by_signature, 0, 1, 1, 1)
         spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
         self.gridLayout.addItem(spacerItem2, 2, 0, 1, 1)
-        self.gridLayout.setRowMinimumHeight(0, 1)
-        self.gridLayout.setRowMinimumHeight(1, 1)
-        self.gridLayout.setRowMinimumHeight(2, 1)
-        self.gridLayout.setRowMinimumHeight(3, 1)
+        self.label_25 = QtWidgets.QLabel(parent=self.tab_4)
+        self.label_25.setObjectName("label_25")
+        self.gridLayout.addWidget(self.label_25, 0, 0, 1, 1)
+        self.search_by_signature = QtWidgets.QLineEdit(parent=self.tab_4)
+        self.search_by_signature.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus)
+        self.search_by_signature.setClearButtonEnabled(True)
+        self.search_by_signature.setObjectName("search_by_signature")
+        self.gridLayout.addWidget(self.search_by_signature, 0, 1, 1, 1)
         self.horizontalLayout_3.addLayout(self.gridLayout)
         spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
         self.horizontalLayout_3.addItem(spacerItem3)
@@ -280,8 +273,8 @@ class Ui_Dialog(object):
         self.label_17.setBuddy(self.box_semester)
         self.label_19.setBuddy(self.box_erstellsemester)
         self.label_16.setBuddy(self.box_fach)
-        self.label_25.setBuddy(self.seach_by_signature)
         self.label_26.setBuddy(self.search_by_title)
+        self.label_25.setBuddy(self.search_by_signature)
 
         self.retranslateUi(Dialog)
         self.tabWidget_2.setCurrentIndex(0)
@@ -296,9 +289,8 @@ class Ui_Dialog(object):
         Dialog.setTabOrder(self.box_erstellsemester, self.box_dauerapp)
         Dialog.setTabOrder(self.box_dauerapp, self.btn_search)
         Dialog.setTabOrder(self.btn_search, self.book_search_result)
-        Dialog.setTabOrder(self.book_search_result, self.seach_by_signature)
-        Dialog.setTabOrder(self.seach_by_signature, self.search_by_title)
-        Dialog.setTabOrder(self.search_by_title, self.book_search)
+        Dialog.setTabOrder(self.book_search_result, self.search_by_signature)
+        Dialog.setTabOrder(self.search_by_signature, self.search_by_title)
 
     def retranslateUi(self, Dialog):
         _translate = QtCore.QCoreApplication.translate
@@ -312,10 +304,9 @@ class Ui_Dialog(object):
         self.label_16.setText(_translate("Dialog", "Fach:"))
         self.btn_search.setText(_translate("Dialog", "Suchen"))
         self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_3), _translate("Dialog", "Statistik"))
-        self.label_25.setText(_translate("Dialog", "Signatur"))
         self.label_26.setText(_translate("Dialog", "Titel"))
-        self.book_search.setText(_translate("Dialog", "Suchen"))
-        self.seach_by_signature.setStatusTip(_translate("Dialog", "Trunkierung mit * am Ende unterstützt"))
+        self.label_25.setText(_translate("Dialog", "Signatur"))
+        self.search_by_signature.setStatusTip(_translate("Dialog", "Trunkierung mit * am Ende unterstützt"))
         self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_4), _translate("Dialog", "Suchen"))
         self.btn_del_select_apparats.setText(_translate("Dialog", "Ausgewählte Löschen"))
         self.btn_notify_for_deletion.setStatusTip(_translate("Dialog", "Zeigt für jeden ausgewählten Apparat eine eMail-Vorlage an"))
diff --git a/src/utils/__init__.py b/src/utils/__init__.py
index c6d5f16..0eafea8 100644
--- a/src/utils/__init__.py
+++ b/src/utils/__init__.py
@@ -1,5 +1,3 @@
-from .blob import create_blob
 from .icon import Icon
-from .pickles import dump_pickle, load_pickle
 from .sortgenerator import app_sort, name_sort
 from .richtext import SemesterDocument
diff --git a/src/utils/richtext.py b/src/utils/richtext.py
index f3ba490..ff2b005 100644
--- a/src/utils/richtext.py
+++ b/src/utils/richtext.py
@@ -56,7 +56,7 @@ def print_document(file: str):
         server.login(settings.mail.user_name, password)
         server.sendmail(sender_email, receiver, mail)
         server.quit()
-        logger.success("Mail sent")
+        log.success("Mail sent")
 
 
 class SemesterError(Exception):
@@ -64,7 +64,7 @@ class SemesterError(Exception):
 
     def __init__(self, message: str):
         super().__init__(message)
-        logger.error(message)
+        log.error(message)
 
     def __str__(self):
         return f"SemesterError: {self.args[0]}"
@@ -107,15 +107,15 @@ class SemesterDocument:
         self.color_blue = RGBColor(0, 0, 255)
         self.filename = filename
         if full:
-            logger.info("Full document generation")
+            log.info("Full document generation")
             self.cleanup
-            logger.info("Cleanup done")
+            log.info("Cleanup done")
             self.make_document()
-            logger.info("Document created")
+            log.info("Document created")
             self.create_pdf()
-            logger.info("PDF created")
-            # print_document(self.filename + ".pdf")
-            logger.info("Document printed")
+            log.info("PDF created")
+            print_document(self.filename + ".pdf")
+            log.info("Document printed")
 
     def set_table_border(self, table):
         """
@@ -247,7 +247,7 @@ class SemesterDocument:
         doc.SaveAs(f"{curdir}/{self.filename}.pdf", FileFormat=17)
         doc.Close()
         word.Quit()
-        logger.debug("PDF saved")
+        log.debug("PDF saved")
 
     @property
     def cleanup(self):
@@ -258,7 +258,7 @@ class SemesterDocument:
     @property
     def send(self):
         print_document(self.filename + ".pdf")
-        logger.debug("Document sent to printer")
+        log.debug("Document sent to printer")
 
 
 class SemapSchilder:
@@ -317,7 +317,7 @@ class SemapSchilder:
     def save_document(self):
         # Save the document
         self.doc.save(f"{self.filename}.docx")
-        logger.debug(f"Document saved as {self.filename}.docx")
+        log.debug(f"Document saved as {self.filename}.docx")
 
     def create_pdf(self):
         # Save the document
@@ -331,7 +331,7 @@ class SemapSchilder:
         doc.SaveAs(f"{curdir}/{self.filename}.pdf", FileFormat=17)
         doc.Close()
         word.Quit()
-        logger.debug("PDF saved")
+        log.debug("PDF saved")
 
     def cleanup(self):
         if os.path.exists(f"{self.filename}.docx"):
@@ -342,7 +342,7 @@ class SemapSchilder:
     @property
     def send(self):
         print_document(self.filename + ".pdf")
-        logger.debug("Document sent to printer")
+        log.debug("Document sent to printer")
 
 
 if __name__ == "__main__":