rebase codebase, delete trunk, move threads to backend

This commit is contained in:
2025-01-14 16:20:08 +01:00
parent fba652006f
commit 08cd18f3f1
106 changed files with 1604 additions and 1057 deletions

View File

@@ -1,6 +1,6 @@
from .admin_console import AdminCommands
from .create_file import recreateElsaFile, recreateFile
from .database import Database
from .delete_temp_contents import delete_temp_contents as tempdelete
from .semester import Semester
from .admin_console import AdminCommands
from .thread_bookgrabber import BookGrabber
from .threads_availchecker import AvailChecker
from .threads_autoadder import AutoAdder

View File

@@ -1,4 +1,3 @@
import hashlib
import random

View File

@@ -28,6 +28,8 @@ from string import ascii_lowercase as lower, digits, punctuation
ascii_lowercase = lower + digits + punctuation
# get the line that called the function
class Database:
database = settings.database
@@ -673,9 +675,6 @@ class Database:
)[0]
return f"{title} " if title is not None else ""
def getSpecificProfData(self, prof_id: Union[str, int], fields: List[str]) -> tuple:
"""A customisable function to get specific data of a professor based on the id
@@ -729,8 +728,9 @@ class Database:
list[tuple]: a list containing all the professors in individual tuples
tuple: (id, titel, fname, lname, fullname, mail, telnr)
"""
profs = self.query_db("SELECT * FROM prof")
profs = self.query_db("SELECT * FROM prof")
return [Prof().from_tuple(prof) for prof in profs]
# Apparat
def getAllAparats(self, deleted=0) -> list[tuple]:
"""Get all the apparats in the database
@@ -865,6 +865,7 @@ class Database:
logger.debug(query)
self.query_db(query)
return None
def getApparatsByProf(self, prof_id: Union[str, int]) -> list[tuple]:
"""Get all apparats based on the professor id
@@ -1362,6 +1363,7 @@ class Database:
entries.append(elsa_id)
query = f"INSERT INTO elsa_media ({', '.join(headers)}) VALUES ({', '.join(['?' for i in range(len(headers))])})"
self.query_db(query, entries)
def getElsaMedia(self, elsa_id: int):
"""get all the media of an ELSA apparat
@@ -1468,7 +1470,8 @@ class Database:
return self.query_db(
"SELECT filename, filetyp FROM elsa_files WHERE elsa_id=?", (elsa_id,)
)
###
###
def createProf(self, profdata: Prof):
logger.debug(profdata)
@@ -1480,30 +1483,32 @@ class Database:
mail = profdata.mail
telnr = profdata.telnr
title = profdata.title
query = f"INSERT INTO prof (fname, lname, fullname, mail, telnr,titel) VALUES ('{fname}','{lname}','{fullname}','{mail}','{telnr}','{title}')"
logger.debug(query)
cursor.execute(query)
conn.commit()
conn.close()
return self.getProfId(profdata)
def getElsaProfId(self, profname):
query = f"SELECT id FROM elsa_prof WHERE fullname = '{profname}'"
data = self.query_db(query)
if data:
return data[0][0]
else: return None
else:
return None
def getElsaProfs(self)->list[str]:
def getElsaProfs(self) -> list[str]:
query = "SELECT fullname FROM elsa_prof"
data = self.query_db(query)
if data:
return [i[0] for i in data]
else: return []
def getProfId(self, profdata: dict|Prof):
else:
return []
def getProfId(self, profdata: dict | Prof):
"""Get the prof ID based on the profdata
Args:
@@ -1518,7 +1523,7 @@ class Database:
fullname = profdata.name()
else:
name = profdata["profname"]
if ","in name:
if "," in name:
fname = name.split(", ")[1].strip()
lname = name.split(", ")[0].strip()
fullname = f"{lname} {fname}"
@@ -1526,28 +1531,30 @@ class Database:
fullname = profdata["profname"]
query = f"SELECT id FROM prof WHERE fullname = '{fullname}'"
logger.debug(query)
cursor.execute(query)
result = cursor.fetchone()
if result:
result = cursor.fetchone()
if result:
return result[0]
else: return None
else:
return None
def getProfByName(self, fullname):
'''Get all Data of the prof based on fullname
"""Get all Data of the prof based on fullname
Args:
fullname (str): The full name of the prof
'''
"""
conn = self.connect()
cursor = conn.cursor()
query = f"SELECT * FROM prof WHERE fullname = '{fullname}'"
logger.debug(query)
result = cursor.execute(query).fetchone()
if result:
return Prof().from_tuple(result)
else: return Prof()
else:
return Prof()
def getProfIDByApparat(self, apprarat_id):
"""Get the prof id based on the semesterapparat id from the database
@@ -1606,4 +1613,5 @@ class Database:
data = self.query_db(query)
if data:
return data[0][0]
else: return None
else:
return None

View File

@@ -1,4 +1,3 @@
CREATE_TABLE_APPARAT = """CREATE TABLE semesterapparat (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT,

View File

@@ -1,10 +1,10 @@
import os
from pathlib import Path
from src import settings
database = settings.database
def delete_temp_contents():
"""
delete_temp_contents deletes the contents of the temp directory.

View File

@@ -1,4 +1,3 @@
import pickle
from typing import Any, ByteString

View File

@@ -2,6 +2,7 @@ import datetime
from src import logger
from dataclasses import dataclass
@dataclass
class Semester:
logger.debug("Semester class loaded")

View File

@@ -1,4 +1,3 @@
from dataclasses import dataclass, field
import yaml

View File

@@ -0,0 +1,188 @@
import sqlite3
from PyQt6.QtCore import QThread
from PyQt6.QtCore import pyqtSignal as Signal
from src.backend import Database
from src.logic.webrequest import BibTextTransformer, WebRequest
class BookGrabber(QThread):
updateSignal = Signal(int, int)
done = Signal()
def __init__(self, appnr):
super(BookGrabber, self).__init__(parent=None)
self.is_Running = True
logger.info("Starting worker thread")
self.data = None
self.app_id = None
self.prof_id = None
self.mode = None
self.book_id = None
self.use_any = False
self.use_exact = False
self.appnr = appnr
self.tstate = (self.app_id, self.prof_id, self.mode, self.data)
def add_values(self, app_id, prof_id, mode, data, any_book=False, exact=False):
self.app_id = app_id
self.prof_id = prof_id
self.mode = mode
self.data = data
self.use_any = any_book
self.use_exact = exact
logger.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))
# print(self.tstate)
def run(self):
self.db = Database()
item = 0
iterdata = self.data
# print(iterdata)
if self.prof_id is None:
self.prof_id = self.db.getProfNameByApparat(self.app_id)
for entry in iterdata:
# print(entry)
signature = str(entry)
logger.info("Processing entry: " + signature)
webdata = WebRequest().set_apparat(self.appnr).get_ppn(entry)
if self.use_any:
webdata = webdata.use_any_book
webdata = webdata.get_data()
if webdata == "error":
continue
bd = BibTextTransformer(self.mode)
print(webdata)
if self.mode == "ARRAY":
if self.use_exact:
bd = bd.use_signature(entry)
bd = bd.get_data(webdata).return_data()
print(bd)
if bd is None:
# bd = BookData
continue
bd.signature = entry
transformer = (
BibTextTransformer("RDS").get_data(webdata).return_data("rds_data")
)
# confirm lock is acquired
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")
state = 0
for result in transformer.RDS_DATA:
# print(result.RDS_LOCATION)
if str(self.app_id) in result.RDS_LOCATION:
state = 1
break
logger.info(f"State of {signature}: {state}")
# print("updating availability of " + str(self.book_id) + " to " + str(state))
try:
self.db.setAvailability(self.book_id, state)
except sqlite3.OperationalError as e:
logger.error(f"Failed to update availability: {e}")
# time.sleep(5)
item += 1
self.updateSignal.emit(item, len(self.data))
logger.info("Worker thread finished")
# self.done.emit()
self.quit()
def stop(self):
self.is_Running = False
# class BookGrabber(object):
# updateSignal = Signal(int, int)
# done = Signal()
# def __init__(self, app_id, prof_id, mode, data, parent=None):
# super(BookGrabber, self).__init__(parent=None)
# self.is_Running = True
# logger = MyLogger("Worker")
# logger.info("Starting worker thread")
# self.data = data
# logger.info(f"Working on {len(self.data)} entries")
# self.app_id = app_id
# self.prof_id = prof_id
# self.mode = mode
# self.book_id = None
# self.state = (self.app_id, self.prof_id, self.mode, self.data)
# # print(self.state)
# logger.info("state: " + str(self.state))
# # time.sleep(2)
# def resetValues(self):
# self.app_id = None
# self.prof_id = None
# self.mode = None
# self.data = None
# self.book_id = None
# def run(self):
# while self.is_Running:
# self.db = Database()
# item = 0
# iterdata = self.data
# # print(iterdata)
# for entry in iterdata:
# # print(entry)
# signature = str(entry)
# logger.info("Processing entry: " + signature)
# webdata = WebRequest().get_ppn(entry).get_data()
# if webdata == "error":
# continue
# bd = BibTextTransformer(self.mode).get_data(webdata).return_data()
# transformer = BibTextTransformer("RDS")
# rds = transformer.get_data(webdata).return_data("rds_availability")
# bd.signature = entry
# # confirm lock is acquired
# 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")
# state = 0
# # print(len(rds.items))
# for rds_item in rds.items:
# sign = rds_item.superlocation
# loc = rds_item.location
# # logger.debug(sign, loc)
# # logger.debug(rds_item)
# if self.app_id in sign or self.app_id in loc:
# state = 1
# break
# logger.info(f"State of {signature}: {state}")
# # print(
# "updating availability of "
# + str(self.book_id)
# + " to "
# + str(state)
# )
# try:
# self.db.setAvailability(self.book_id, state)
# except sqlite3.OperationalError as e:
# logger.error(f"Failed to update availability: {e}")
# # time.sleep(5)
# item += 1
# self.updateSignal.emit(item, len(self.data))
# logger.info("Worker thread finished")
# # self.done.emit()
# self.stop()
# if not self.is_Running:
# break
# def stop(self):
# self.is_Running = False

View File

@@ -0,0 +1,50 @@
import time
# from icecream import ic
from PyQt6.QtCore import QThread
from PyQt6.QtCore import pyqtSignal as Signal
from src.backend import Database
# from src.transformers import RDS_AVAIL_DATA
class AutoAdder(QThread):
updateSignal = Signal(int)
setTextSignal = Signal(int)
progress = Signal(int)
def __init__(self, data=None, app_id=None, prof_id=None, parent=None):
super().__init__(parent)
self.data = data
self.app_id = app_id
self.prof_id = prof_id
# print("Launched AutoAdder")
# print(self.data, self.app_id, self.prof_id)
def run(self):
self.db = Database()
# show the dialog, start the thread to gather data and dynamically update progressbar and listwidget
logger.info("Starting worker thread")
item = 0
for entry in self.data:
try:
self.updateSignal.emit(item)
self.setTextSignal.emit(entry)
item += 1
self.progress.emit(item)
time.sleep(1)
except Exception as e:
# print(e)
logger.exception(
f"The query failed with message {e} for signature {entry}"
)
continue
if item == len(self.data):
logger.info("Worker thread finished")
# teminate thread
self.finished.emit()

View File

@@ -0,0 +1,72 @@
import time
# from icecream import ic
from PyQt6.QtCore import QThread
from PyQt6.QtCore import pyqtSignal as Signal
from src.backend.database import Database
from src.logic.webrequest import BibTextTransformer, WebRequest
# from src.transformers import RDS_AVAIL_DATA
class AvailChecker(QThread):
updateSignal = Signal(str, int)
updateProgress = Signal(int, int)
def __init__(
self, links: list = None, appnumber: int = None, parent=None, books=list[dict]
):
if links is None:
links = []
super().__init__(parent)
logger.info("Starting worker thread")
logger.info(
"Checking availability for "
+ str(links)
+ " with appnumber "
+ str(appnumber)
+ "..."
)
self.links = links
self.appnumber = appnumber
self.books = books
logger.info(
f"Started worker with appnumber: {self.appnumber} and links: {self.links} and {len(self.books)} books..."
)
time.sleep(2)
def run(self):
self.db = Database()
state = 0
count = 0
for link in self.links:
logger.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")
book_id = None
for item in rds.items:
sign = item.superlocation
loc = item.location
# # print(item.location)
if self.appnumber in sign or self.appnumber in loc:
state = 1
break
for book in self.books:
if book["bookdata"].signature == link:
book_id = book["id"]
break
logger.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")
# teminate thread
self.quit()