update code, switch to loguru

This commit is contained in:
2025-01-10 09:35:18 +01:00
parent e915b47dda
commit 0d7dc28876
17 changed files with 127 additions and 162 deletions

View File

@@ -0,0 +1 @@
0.2.0

View File

@@ -29,6 +29,4 @@ shortcuts:
advanced_refresh: false
catalogue: true
debug: false
log_debug: false
ic_logging: false
documentation: true

View File

@@ -8,16 +8,21 @@ with open("pyproject.toml", "r") as file:
break
with open(".version", "r") as file:
version = file.read().strip()
print(f"Name: {name}, Version: {version}")
def rename_folders():
for folder in os.listdir("dist"):
if folder.endswith(".dist"):
if "-dev" in folder:
os.rename(f"dist/{folder}", f"dist/{name}-dev")
if "_dev" in folder:
os.rename(
os.path.join("dist", folder),
os.path.join("dist", f"{name}-{version}-dev"),
)
else:
os.rename(f"dist/{folder}", f"dist/{name}-{version}")
os.rename(
os.path.join("dist", folder),
os.path.join("dist", f"{name}-{version}"),
)
if __name__ == "__main__":
rename_folders()

View File

@@ -1,5 +1,9 @@
import sys
from config import Config
from loguru import logger
from datetime import datetime
import atexit
import argparse
__version__ = "0.2.0"
__author__ = "Alexander Kirchner"
__email__ = "alexander.kirchner@ph-freiburg.de"
@@ -8,54 +12,60 @@ docport = 6543
config = Config("config/settings.yaml")
valid_args = ["--debug", "--log", "--no-backup", "--ic-logging", "--version", "-h","--no-documentation"]
_config = config
# Store original values that might be overridden by CLI
args_description = {
"--debug": "Enable debug mode",
"--log": "Enable logging",
"--no-backup": "Disable database backup",
"--ic-logging": "Enable icecream logging (not available in production)",
"--version": "Show version",
"-h": "Show help message and exit",
"--no-documentation": "Disable documentation server and shortcut"
}
args = sys.argv[1:]
if any(arg not in valid_args for arg in args):
print("Invalid argument present")
print([arg for arg in args if arg not in valid_args])
sys.exit()
def help():
print("Ausleihsystem")
print("Ein Ausleihsystem für Handbibliotheken")
print("Version: {}".format(__version__))
print("Valide Argumente:")
print("args")
print("--------")
print("usage: main.py [-h] [--debug] [--log] [--no-backup] [--ic-logging] [--version] [--no-documentation]")
print("options:")
for arg in valid_args:
print(f"{arg} : {args_description[arg]}")
# based on the arguments, set the config values
if"-h" in args:
help()
sys.exit()
if "--debug" in args:
args = argparse.ArgumentParser()
args.add_argument("--debug", help="Debugging mode", action="store_true")
args.add_argument("--no-backup", help="Disable backups", action="store_true")
args.add_argument("--version", help="Print version", action="store_true")
args.add_argument(
"--no-documentation", help="Disable documentation", action="store_true"
)
args = args.parse_args()
if args.version:
print(f"Version: {__version__}")
sys.exit(0)
# Override config values temporarily without saving
changes_made = False
if args.debug:
config.debug = True
if "--log" in args:
config.log_debug = True
if "--no-backup" in args:
config.no_backup = True
if "--ic-logging" in args:
config.ic_logging = True
if "--no-documentation" in args:
changes_made = True
if args.no_backup:
config.database.do_backup = False
changes_made = True
if args.no_documentation:
config.documentation = False
if "--version" in args:
print(__version__)
sys.exit()
changes_made = True
if changes_made:
config.save()
def restore_config():
global _config
config._config = _config
config.save()
log.info("Restored configuration")
atexit.register(restore_config)
log = logger
log.remove()
log.add("logs/application.log", rotation="1 week", compression="zip")
# add a log for the current day
log.add(
f"logs/{datetime.now().strftime('%Y-%m-%d')}.log",
rotation="1 day",
compression="zip",
)
print(config.debug)
if config.debug:
import sys
log.add(
sys.stderr,
)

View File

@@ -1,12 +1,10 @@
import requests
from bs4 import BeautifulSoup
from src import config
from src import config, log
from src.schemas import Book
from src.utils import Log
URL = "https://rds.ibs-bw.de/phfreiburg/opac/RDSIndex/Search?type0%5B%5D=allfields&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=au&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=ti&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=ct&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=isn&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=ta&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=co&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=py&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=pp&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=pu&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=si&lookfor0%5B%5D={}&join=AND&bool0%5B%5D=AND&type0%5B%5D=zr&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=cc&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND"
BASE = "https://rds.ibs-bw.de"
log = Log("Catalogue")
class Catalogue:
def __init__(self, timeout=5):

View File

@@ -1,12 +1,11 @@
import sqlite3 as sql
import os
import shutil
from src import config
from src import config, log
from src.schemas import USERS, MEDIA, LOANS, User, Book, Loan
from src.utils import stringToDate, Log, debugMessage as dbg
from src.utils import stringToDate
from PyQt6 import QtCore
log = Log("Database")
FILE = config.database.name
class Database:
def __init__(self, db_path: str = None):
@@ -25,12 +24,12 @@ class Database:
try:
os.makedirs(config.database.path)
except FileNotFoundError:
dbg(self.db_path)
log.error(f"Path {config.database.path} not found")
if not os.path.exists(config.database.backupLocation):
os.makedirs(config.database.backupLocation)
#if main path does not exist, try to create it. if that fails, use the backuplocation
dbg(self.db_path)
log.debug("Checking Database Path", self.db_path)
self.checkDatabaseStatus()
def handle_folder_reachability(self, original_path, backup_path):
@@ -59,7 +58,7 @@ class Database:
return backup_path +"/" + FILE
else:
dbg("Original Path Exists, using this path")
log.info("Original Path Exists, using this path")
# Original folder is reachable, check for backup
if os.path.exists(backup_file):
# Restore backup

4
src/logic/k10plus.py Normal file
View File

@@ -0,0 +1,4 @@
import requests
URL = "https://sru.k10plus.de/opac-de-627!rec=1?version=1.1&operation=searchRetrieve&query="

View File

@@ -1,8 +1,9 @@
from src import log
from .sources.Ui_dialog_createUser import Ui_Dialog
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtGui import QRegularExpressionValidator
from src.logic import Database
from src.utils import Icon, Log
from src.utils import Icon
class CreateUser(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, fieldname, data):
@@ -38,6 +39,7 @@ class CreateUser(QtWidgets.QDialog, Ui_Dialog):
self.userno.textChanged.connect(
lambda: self.validateInputUserno(self.userno.text(), "int")
)
log.info("User creation dialog opened")
def checkFields(self):
if (
self.username.hasAcceptableInput()
@@ -58,7 +60,11 @@ class CreateUser(QtWidgets.QDialog, Ui_Dialog):
usermail = self.user_mail.text()
if self.db.insertUser(username, userno, usermail):
self.userid = userno
log.info(f"User {username} created")
else:
log.error(
f"User {username} could not be created, input was: {username}, {userno}, {usermail}"
)
self.setStatusTipMessage(
"Benutzer konnte nicht erstellt werden, bitte überprüfen Sie die Eingaben"
)

View File

@@ -1,9 +1,9 @@
from .sources.Ui_main_Loans import Ui_MainWindow
from PyQt6 import QtCore, QtGui, QtWidgets
from src import log
from .user import UserUI
from src.logic import Database
from src.utils import stringToDate, Icon
from src.utils import debugMessage as dbg
from icecream import ic
TABLETOFIELDTRANSLATE = {
@@ -23,8 +23,7 @@ class LoanWindow(QtWidgets.QMainWindow, Ui_MainWindow):
QtWidgets.QHeaderView.ResizeMode.Stretch
)
self.db = Database()
self.loans = []
self.loadLoans()
self.loans = self.loadLoans()
# lineedits
self.searchbar.textChanged.connect(self.limitResults)
@@ -37,6 +36,7 @@ class LoanWindow(QtWidgets.QMainWindow, Ui_MainWindow):
# table
self.loanTable.doubleClicked.connect(self.showUser)
log.info("Loan history window opened")
self.show()
def selfpass(self):
@@ -44,7 +44,7 @@ class LoanWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def insertRow(self, data):
dbg(contents=data)
log.debug(f"Inserting row: {data}")
retdate = ""
if data.returned_date != "":
@@ -77,9 +77,10 @@ class LoanWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def loadLoans(self):
loans = self.db.getAllLoans()
loanlist = []
for loan in loans:
self.insertRow(loan)
self.loans = loans
return loanlist
def filterResults(self):
mode = (
@@ -112,7 +113,7 @@ class LoanWindow(QtWidgets.QMainWindow, Ui_MainWindow):
limiter = str(limiter)
searchfield = self.searchFields.currentText()
searchfield = TABLETOFIELDTRANSLATE[searchfield]
dbg(limiter=limiter, search=searchfield)
log.debug(f"Searching for: {limiter} in {searchfield}")
self.loanTable.setRowCount(0)
for loan in self.loans:
fielddata = eval(f"loan.{searchfield}")

View File

@@ -2,10 +2,9 @@ import sys
import atexit
import datetime
import webbrowser
from src import config, __email__, docport
from src import config, __email__, docport, log
from src.logic import Database, Catalogue, Backup
from src.utils import stringToDate, Icon, Log
from src.utils import debugMessage as dbg
from src.utils import stringToDate, Icon
from src.utils.createReport import generate_report
from src.schemas import Book
from .sources.Ui_main_UserInterface import Ui_MainWindow
@@ -22,8 +21,6 @@ from omegaconf import OmegaConf
from src.logic.documentation_thread import DocumentationThread
backup = Backup()
cat = Catalogue()
log = Log("main")
dbg(backup=config.database.do_backup, catalogue=config.catalogue)
def getShortcut(shortcuts, name):
shortcut = [cut for cut in shortcuts if cut["name"] == name][0]
@@ -183,7 +180,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
def restart(self):
#log restart
dbg("Restarting Program")
log.info("Restarting Program")
import os
python_executable = sys.executable
args = sys.argv[:]
@@ -192,8 +189,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
def changeMode(self):
log.info("Changing Mode")
dbg(f"Current mode: {self.activeState}")
log.info("Changing Mode, current mode is {}", self.activeState)
self.input_username.clear()
stayReturn = False
if config.advanced_refresh and self.userdata.toPlainText() != "":
@@ -216,7 +212,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
self.activateReturnMode()
def activateLoanMode(self):
dbg("Activating Loan Mode")
log.info("Activating Loan Mode")
self.input_username.setEnabled(True)
self.input_userno.setEnabled(True)
self.duedate.setEnabled(True)
@@ -234,7 +230,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
self.input_file_ident.setEnabled(True)
def activateReturnMode(self):
dbg("Activating Return Mode")
log.info("Activating Return Mode")
self.input_username.setEnabled(False)
self.input_userno.setEnabled(False)
# set mode background color to orange
@@ -326,7 +322,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
self.mode.setText("Ausleihe")
#print(self.activeUser.__dict__)
loans = self.db.getActiveLoans(self.activeUser.id)
dbg(loans=loans)
log.debug("Active Loans", loans)
self.btn_show_lentmedia.setText(loans)
retdate = self.db.selectClosestReturnDate(self.activeUser.id)
if retdate:
@@ -375,16 +371,16 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
self.mediaAdd(value)
self.input_file_ident.setFocus()
def mediaAdd(self, identifier):
dbg("Adding Media", identifier = identifier)
log.info("Adding Media", identifier=identifier)
self.input_file_ident.clear()
self.input_file_ident.setEnabled(False)
user_id = self.activeUser.id
media = Book(signature=identifier)
book_id = self.db.checkMediaExists(media)
dbg(f"Book ID: {book_id}, User ID: {user_id}", media=media)
log.debug(f"Book ID: {book_id}, User ID: {user_id}", media=media)
if not book_id:
dbg("Book not found, searching catalogue")
log.info("Book not found, searching catalogue")
if config.catalogue == True:
media = cat.get_book(identifier)
if not media:
@@ -441,7 +437,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
for entry in newentries:
book = self.db.getMedia(entry)
self.loanMedia(user_id, [entry], book)
dbg("inserted duplicated book into database")
log.info("inserted duplicated book into database")
return
else:
#print("Book not loaned, loaning now")
@@ -506,7 +502,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
self.setStatusTipMessage("Buch nicht entliehen")
self.input_file_ident.clear()
else:
dbg("Book not found")
log.error("Book not found, identifier", identifier)
#print("Book not found")
#self.input_file_ident.setPlaceholderText(f"Buch {identifier} nicht gefunden")
@@ -520,13 +516,13 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
dialog.setText(message)
dialog.exec()
def exit_handler():
dbg("Exiting, creating backup")
log.info("Exiting, creating backup")
app = QtWidgets.QApplication(sys.argv)
#print(backup.backup)
# generate report if monday
if datetime.datetime.now().weekday() == config.report.report_day:
generate_report()
dbg("Generated Report")
log.info("Generated Report")
Database().renameInactiveUsers()
if config.database.do_backup:
state = backup.createBackup()
@@ -541,7 +537,7 @@ def exit_handler():
dialog.setText("Backup konnte nicht erstellt werden")
dialog.exec()
dbg("Exiting", backupstate=state)
log.info("Exiting, backup:", state)
else:
dialog = QtWidgets.QMessageBox()
# set icon

View File

@@ -1,8 +1,7 @@
from .sources.Ui_dialog_settings import Ui_Dialog
from PyQt6 import QtWidgets, QtCore
from src import config, log
from src.utils import Icon
from src import config
from src.utils import debugMessage as dbg
from omegaconf import OmegaConf
import os
@@ -192,7 +191,7 @@ class Settings(QtWidgets.QDialog, Ui_Dialog):
if changed == original:
self.settingschanged = False
self.restart_required = False
dbg("Settings not changed")
log.info("Settings not changed")
else:
self.settingschanged = True
#compare if database or shortcuts were changed
@@ -200,7 +199,11 @@ class Settings(QtWidgets.QDialog, Ui_Dialog):
shortcuts = self.shortcuts == self.sortShortcuts(changed.shortcuts)
if not database or not shortcuts:
self.restart_required = True
dbg(f"Settings changed, restart required: {self.restart_required}",database=database,shortcuts=shortcuts)
log.info(
f"Settings changed, restart required: {self.restart_required}",
database=database,
shortcuts=shortcuts,
)
# save the new settings
if self.settingschanged:

View File

@@ -1,10 +1,10 @@
from .sources.Ui_main_userData import Ui_MainWindow
from PyQt6 import QtCore, QtGui, QtWidgets
from src import log
from src.logic import Database
from src.schemas import User
from .extendLoan import ExtendLoan
from src.utils import stringToDate, Icon
from src.utils import debugMessage as dbg
TABLETOFIELDTRANSLATE = {
"Titel": "title",
@@ -95,7 +95,6 @@ class UserUI(QtWidgets.QMainWindow, Ui_MainWindow):
limiter = self.searchbox.text().lower()
searchfield = self.searchfilter.currentText()
searchfield = TABLETOFIELDTRANSLATE[searchfield]
# dbg(limiter=limiter, search=searchfield)
self.UserMediaTable.setRowCount(0)
for loan in self.userMedia:
@@ -166,7 +165,7 @@ class UserUI(QtWidgets.QMainWindow, Ui_MainWindow):
continue
elif mode == "overdue":
# book not returned and todays date is greater than todate
dbg(book=book)
log.debug("Book: {}".format(book))
if book.returned_date is not None:
continue
# if todate is greater than current date, continue

View File

@@ -1,5 +1,3 @@
from .log import Log
from .icon import Icon
from .debug import debugMessage
from .stringtodate import stringToDate
from .documentation import launch_documentation

View File

@@ -1,18 +0,0 @@
from src import config
from icecream import ic
from src.utils import Log
log = Log("debugMessage")
def debugMessage(*args, **kwargs):
startmessage = "Logging debug message"
# join args and kwargs to a string
message = " ".join(args)
for key, value in kwargs.items():
message += f" {key}: {value}"
if config.debug:
if config.log_debug:
log.info(f"{startmessage}: {message}")
if config.ic_logging == True:
ic(message)
else: print(message)
return message

View File

@@ -1,7 +1,8 @@
from pyramid.config import Configurator
from wsgiref.simple_server import make_server
from src import docport
from src import docport, log
import os
import sys
def website():
config = Configurator()
@@ -14,8 +15,17 @@ def website():
def launch_documentation():
app = website()
server = make_server('localhost', 6543, app)
print("Serving MkDocs documentation on http://0.0.0.0:{}".format(docport))
server.serve_forever()
log.info("Serving MkDocs documentation on http://0.0.0.0:{}".format(docport))
with open(os.devnull, "w") as devnull:
old_stdout = sys.stdout
old_stderr = sys.stderr
sys.stdout = devnull
sys.stderr = devnull
try:
server.serve_forever()
finally:
sys.stdout = old_stdout
sys.stderr = old_stderr
if __name__ == '__main__':
pass

View File

@@ -1,26 +0,0 @@
import logging
class Log:
def __init__(self, name):
self.logger = logging.getLogger(name)
self.logger.setLevel(logging.DEBUG)
self.formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
self.file_handler = logging.FileHandler("log.log")
self.file_handler.setLevel(logging.DEBUG)
self.file_handler.setFormatter(self.formatter)
self.logger.addHandler(self.file_handler)
def info(self, message):
self.logger.info(message)
def debug(self, message):
self.logger.debug(message)
def error(self, message):
self.logger.error(message)
def warning(self, message):
self.logger.warning(message)

View File

@@ -1,6 +1,6 @@
# import qdate
from PyQt6 import QtCore
from .debug import debugMessage
from src import log
def stringToDate(date: str) -> QtCore.QDate:
"""Takes an input string and returns a QDate object.
@@ -10,7 +10,7 @@ def stringToDate(date: str) -> QtCore.QDate:
Returns:
QtCore.QDate: the QDate object in string format DD.MM.yyyy
"""
debugMessage(date=date)
log.debug(f"stringToDate: {date}")
if not date:
return ""
if isinstance(date, QtCore.QDate):
@@ -21,22 +21,3 @@ def stringToDate(date: str) -> QtCore.QDate:
month = datedata[1]
year = datedata[0]
return QtCore.QDate(int(year), int(month), int(day))
# else:
# datedata = date.split(" ")[1:]
# month = datedata[0]
# day = datedata[1]
# year = datedata[2]
# month = month.replace("Jan", "01")
# month = month.replace("Feb", "02")
# month = month.replace("Mar", "03")
# month = month.replace("Apr", "04")
# month = month.replace("May", "05")
# month = month.replace("Jun", "06")
# month = month.replace("Jul", "07")
# month = month.replace("Aug", "08")
# month = month.replace("Sep", "09")
# month = month.replace("Oct", "10")
# month = month.replace("Nov", "11")
# month = month.replace("Dec", "12")
# return QtCore.QDate(int(year), int(month), int(day)).toString("dd.MM.yyyy")