rebase codebase, delete trunk, move threads to backend
This commit is contained in:
@@ -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
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import hashlib
|
||||
import random
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
CREATE_TABLE_APPARAT = """CREATE TABLE semesterapparat (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name TEXT,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import pickle
|
||||
from typing import Any, ByteString
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import datetime
|
||||
from src import logger
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Semester:
|
||||
logger.debug("Semester class loaded")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
import yaml
|
||||
|
||||
188
src/backend/thread_bookgrabber.py
Normal file
188
src/backend/thread_bookgrabber.py
Normal 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
|
||||
50
src/backend/threads_autoadder.py
Normal file
50
src/backend/threads_autoadder.py
Normal 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()
|
||||
72
src/backend/threads_availchecker.py
Normal file
72
src/backend/threads_availchecker.py
Normal 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()
|
||||
Reference in New Issue
Block a user