From caa96f9565fb8dc23c3c82558920a9262fe86998 Mon Sep 17 00:00:00 2001
From: WorldTeacher <41587052+WorldTeacher@users.noreply.github.com>
Date: Tue, 11 Jun 2024 09:41:21 +0200
Subject: [PATCH] delete files
---
src/backend/olddatabase.py | 753 --------
src/logic/userInterface.py | 2453 ---------------------------
src/ui/Ui_plotdata.py | 47 -
src/ui/Ui_semesterapparat_ui.ts | 232 ---
src/ui/Ui_setupwizard.py | 86 -
src/ui/dialogs/apparat_extend_ui.py | 130 --
src/ui/dialogs/confirm_extend_ui.py | 81 -
src/ui/dialogs/ext_app.py | 57 -
src/ui/mainwindow.py | 408 -----
src/ui/plotdata.ui | 64 -
src/ui/plotdata_ui.py | 47 -
src/ui/resources.qrc | 14 -
src/ui/resources_rc.py | 162 --
src/ui/sap.py | 573 -------
src/ui/semesterapparat_ui.ts | 234 ---
src/ui/semesterapparat_ui_ui.py | 1963 ---------------------
src/ui/setupwizard.ui | 149 --
src/ui/setupwizard_ui.py | 151 --
18 files changed, 7604 deletions(-)
delete mode 100644 src/backend/olddatabase.py
delete mode 100644 src/logic/userInterface.py
delete mode 100644 src/ui/Ui_plotdata.py
delete mode 100644 src/ui/Ui_semesterapparat_ui.ts
delete mode 100644 src/ui/Ui_setupwizard.py
delete mode 100644 src/ui/dialogs/apparat_extend_ui.py
delete mode 100644 src/ui/dialogs/confirm_extend_ui.py
delete mode 100644 src/ui/dialogs/ext_app.py
delete mode 100644 src/ui/mainwindow.py
delete mode 100644 src/ui/plotdata.ui
delete mode 100644 src/ui/plotdata_ui.py
delete mode 100644 src/ui/resources.qrc
delete mode 100644 src/ui/resources_rc.py
delete mode 100644 src/ui/sap.py
delete mode 100644 src/ui/semesterapparat_ui.ts
delete mode 100644 src/ui/semesterapparat_ui_ui.py
delete mode 100644 src/ui/setupwizard.ui
delete mode 100644 src/ui/setupwizard_ui.py
diff --git a/src/backend/olddatabase.py b/src/backend/olddatabase.py
deleted file mode 100644
index fb3a941..0000000
--- a/src/backend/olddatabase.py
+++ /dev/null
@@ -1,753 +0,0 @@
-import datetime
-import os
-
-# from src.data import pickles
-import pickle
-import re
-import shutil
-import sqlite3 as sql3
-import tempfile
-from typing import Any
-
-from omegaconf import OmegaConf
-
-from src.logic.constants import SEMAP_MEDIA_ACCOUNTS
-from src.logic.dataclass import ApparatData, BookData
-from src.logic.log import MyLogger
-
-# from icecream import ic
-config = OmegaConf.load("config.yaml")
-
-logger = MyLogger("Database")
-
-
-class Database:
- logger.log_info("Database imported")
-
- def __init__(self) -> None:
- # TODO: change path later on to a variable based on the settings
- self.database_path = f"{config.database.path}{config.database.name}"
- # ic(self.database_path)
- self.database_path = "sap.db"
- logger.log_info("Connecting to database")
- self.database = sql3.connect(self.database_path)
- self.cur = self.database.cursor()
-
- pass
-
- def create_database(self):
- # create database from template
- subjects = config.subjects
- for subject in subjects:
- self.cur.execute(f"INSERT INTO subjects (name) VALUES ('{subject}')")
- self.database.commit()
-
- def create_blob(self, file):
- with open(file, "rb") as f:
- blob = f.read()
- return blob
-
- def recreate_file(self, filename, app_id: int):
- blob = self.get_blob(filename, app_id)
- # write the blob to the file and save it to a preset destination
- # with open(filename, "wb") as f:
- # f.write(blob)
- # use tempfile to create a temporary file
- if not os.path.exists(config.database.tempdir):
- os.mkdir(config.database.tempdir)
- tempfile.NamedTemporaryFile(
- filename=filename, delete=False, dir=config.database.tempdir, mode="wb"
- ).write(blob)
-
- # user = os.getlogin()
- # home = os.path.expanduser("~")
-
- # # check if the folder exists, if not, create it
- # if not os.path.exists(f"{home}/Desktop/SemApp/{user}"):
- # os.mkdir(f"{home}/Desktop/SemApp/{user}")
- # shutil.move(filename, f"{home}/Desktop/SemApp/{user}")
-
- def get_blob(self, filename: str, app_id: int):
- query = f"SELECT fileblob FROM files WHERE filename='{filename}' AND app_id={app_id}"
- logger.log_info(f"Retrieving blob for {filename}, Appid {app_id} from database")
- result = self.cur.execute(query).fetchone()
- return result[0]
-
- def get_kto_no(self, app_id: int):
- query = f"SELECT konto FROM semesterapparat WHERE id={app_id}"
- result = self.cur.execute(query).fetchone()
- return result[0]
-
- def insert_file(self, file: list[dict], app_id: int, prof_id):
- for f in file:
- filename = f["name"]
- path = f["path"]
- filetyp = f["type"]
- print(f"filename: {filename}, path: {path}, filetyp: {filetyp}")
- if path == "Database":
- continue
- blob = self.create_blob(path)
-
- query = "INSERT OR IGNORE INTO files (filename, fileblob, app_id, filetyp,prof_id) VALUES (?, ?, ?, ?,?)"
- params = (filename, blob, app_id, filetyp, prof_id)
- self.cur.execute(query, params)
- logger.log_info(
- f"Inserted {len(file)} file(s) of Apparat {app_id} into database"
- )
- self.database.commit()
-
- def get_files(self, app_id: int, prof_id: int):
- query = f"SELECT filename, filetyp FROM files WHERE app_id={app_id} AND prof_id={prof_id}"
- result: list[tuple] = self.cur.execute(query).fetchall()
- return result
-
- def get_prof_name_by_id(self, id, add_title: bool = False):
- if add_title is True:
- query = f"SELECT titel, fname, lname FROM prof WHERE id={id}"
- result = self.cur.execute(query).fetchone()
- name = " ".join(result[0:3])
- return name
- else:
- query = f"SELECT fullname FROM prof WHERE id={id}"
- print(query)
- result = self.cur.execute(query).fetchone()
- name = result[0]
- return name
-
- def get_prof_id(self, profname: str):
- query = f"SELECT id FROM prof WHERE fullname='{profname.replace(',', '')}'"
- result = self.cur.execute(query).fetchone()
- if result is None:
- return None
- return self.cur.execute(query).fetchone()[0]
-
- def get_app_id(self, appname: str):
- query = f"SELECT id FROM semesterapparat WHERE name='{appname}'"
- result = self.cur.execute(query).fetchone()
- if result is None:
- return None
- return self.cur.execute(query).fetchone()[0]
-
- def get_profs(self):
- query = "select * from prof"
- return self.cur.execute(query).fetchall()
-
- def app_exists(self, appnr: str) -> bool:
- query = f"SELECT appnr FROM semesterapparat WHERE appnr='{appnr}'"
- result = self.cur.execute(query).fetchone()
- if result is None:
- return False
- return True
-
- def get_prof_data(self, profname: str = None, id: int = None) -> dict[str, str]:
- if profname is not None:
- profname = profname.replace(",", "")
- profname = re.sub(r"\s+", " ", profname).strip()
- if id:
- query = "Select prof_id FROM semesterapparat WHERE appnr=?"
- params = (id,)
- result = self.cur.execute(query, params).fetchone()
- id = result[0]
- query = (
- f"SELECT * FROM prof WHERE fullname='{profname}'"
- if id is None
- else f"SELECT * FROM prof WHERE id={id}"
- )
- result = self.cur.execute(query).fetchone()
- return_data = {
- "prof_title": result[1],
- "profname": f"{result[3], result[2]}",
- "prof_mail": result[5],
- "prof_tel": result[6],
- "id": result[0],
- }
- print(return_data)
- # select the entry that contains the first name
- return return_data
-
- def set_new_sem_date(self, appnr, new_sem_date, dauerapp=False):
- # Todo: use extend_semester in new release
- date = datetime.datetime.now().strftime("%Y-%m-%d")
-
- query = f"UPDATE semesterapparat SET verlängert_am='{date}', verlängerung_bis='{new_sem_date}' WHERE appnr='{appnr}'"
- if dauerapp is not False:
- query = f"UPDATE semesterapparat SET verlängert_am='{date}', verlängerung_bis='{new_sem_date}', dauerapp='{dauerapp} WHERE appnr='{appnr}'"
- self.cur.execute(query)
-
- self.database.commit()
-
- def create_apparat(self, ApparatData: ApparatData):
- prof_id = self.get_prof_id(ApparatData.profname)
- app_id = self.get_app_id(ApparatData.appname)
- if app_id is None:
- if prof_id is None:
- self.create_prof(ApparatData.get_prof_details())
- prof_id = self.get_prof_id(ApparatData.profname)
-
- query = f"INSERT OR IGNORE INTO semesterapparat (appnr, name, erstellsemester, dauer, prof_id, fach,deletion_status,konto) VALUES ('{ApparatData.appnr}', '{ApparatData.appname}', '{ApparatData.semester}', '{ApparatData.dauerapp}', {prof_id}, '{ApparatData.app_fach}', '{ApparatData.deleted}', '{SEMAP_MEDIA_ACCOUNTS[ApparatData.appnr]}')"
- print(query)
- self.cur.execute(query)
- self.database.commit()
- logger.log_info(f"Created new apparat {ApparatData.appname}")
- app_id = self.get_app_id(ApparatData.appname)
- # if ApparatData.media_list is not None: #! Deprecated
- # for media in ApparatData.media_list:
- # self.insert_file(media, app_id)
- # self.database.commit()
- return app_id
-
- def create_prof(self, prof_details: dict):
- prof_title = prof_details["prof_title"]
- prof_fname = prof_details["profname"].split(",")[1]
- prof_fname = prof_fname.strip()
- prof_lname = prof_details["profname"].split(",")[0]
- prof_lname = prof_lname.strip()
- prof_fullname = prof_details["profname"].replace(",", "")
- prof_mail = prof_details["prof_mail"]
- prof_tel = prof_details["prof_tel"]
-
- query = f'INSERT OR IGNORE INTO prof (titel, fname, lname, fullname, mail, telnr) VALUES ("{prof_title}", "{prof_fname}", "{prof_lname}", "{prof_fullname}", "{prof_mail}", "{prof_tel}")'
- self.cur.execute(query)
- self.database.commit()
- pass
-
- def get_apparat_nrs(self) -> list:
- try:
- self.cur.execute(
- "SELECT appnr FROM semesterapparat Where deletion_status=0"
- )
- except sql3.OperationalError:
- return []
- return [i[0] for i in self.cur.fetchall()]
-
- def get_all_apparts(self, deleted=0):
-
- self.cur.execute(
- f"SELECT * FROM semesterapparat WHERE deletion_status={deleted}"
- )
- return self.cur.fetchall()
-
- #
- def get_app_data(self, appnr, appname) -> ApparatData:
- result = self.cur.execute(
- f"SELECT * FROM semesterapparat WHERE appnr='{appnr}' AND name='{appname}'"
- ).fetchone()
- print(f"result: {result}")
- # app_id=result[0]
- data = ApparatData()
- data.appnr = appnr
- data.app_fach = result[3]
- data.appname = result[1]
- profname = self.get_prof_name_by_id(result[2])
- # set profname to lastname, firstname
- profname = f"{profname.split(' ')[0]}, {profname.split(' ')[1]}"
- data.profname = profname
- prof_data = self.get_prof_data(data.profname)
- data.prof_mail = prof_data["prof_mail"]
- data.prof_tel = prof_data["prof_tel"]
- data.prof_title = prof_data["prof_title"]
- data.erstellsemester = result[5]
- data.semester = result[8]
- data.deleted = result[9]
- data.apparat_adis_id = result[12]
- data.prof_adis_id = None
-
- print(data)
- # data.media_list=self.get_media(app_id)
-
- return data
-
- def add_medium(self, bookdata: BookData, app_id: str, prof_id: str, *args):
- # insert the bookdata into the media table
- # try to retrieve the bookdata from the media table, check if the to be inserted bookdata is already in the table for the corresponding apparat
- # if yes, do not insert the bookdata
- # if no, insert the bookdata
- t_query = (
- f"SELECT bookdata FROM media WHERE app_id={app_id} AND prof_id={prof_id}"
- )
- # print(t_query)
- result = self.cur.execute(t_query).fetchall()
- result = [pickle.loads(i[0]) for i in result]
- if bookdata in result:
- print("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=?"
- )
- params = (app_id, prof_id, pickle.dumps(bookdata))
- result = self.cur.execute(query, params).fetchone()
- if result[0] == 1:
- print("Book was deleted, updating bookdata")
- query = "UPDATE media SET deleted=0 WHERE app_id=? AND prof_id=? AND bookdata=?"
- params = (app_id, prof_id, pickle.dumps(bookdata))
- self.cur.execute(query, params)
- self.database.commit()
- return
-
- query = (
- "INSERT INTO media (bookdata, app_id, prof_id,deleted) VALUES (?, ?, ?,?)"
- )
- converted = pickle.dumps(bookdata)
- params = (converted, app_id, prof_id, 0)
- self.cur.execute(query, params)
- self.database.commit()
-
- def request_medium(self, app_id, prof_id, signature) -> int:
- query = "SELECT bookdata, id FROM media WHERE app_id=? AND prof_id=?"
- params = (app_id, prof_id)
- result = self.cur.execute(query, params).fetchall()
- books = [(i[1], pickle.loads(i[0])) for i in result]
- print(books)
- book = [i[0] for i in books if i[1].signature == signature]
- return book[0]
-
- def add_message(self, message: dict, user, appnr):
- def __get_user_id(user):
- query = "SELECT id FROM user WHERE username=?"
- params = (user,)
- result = self.cur.execute(query, params).fetchone()
- return result[0]
-
- user_id = __get_user_id(user)
- query = "INSERT INTO messages (message, user_id, remind_at) VALUES (?, ?, ?)"
- params = (message["message"], user_id, message["remind_at"])
- self.cur.execute(query, params)
- self.database.commit()
-
- def get_messages(self, date: str):
- def __get_user_name(id):
- query = "SELECT username FROM user WHERE id=?"
- params = (id,)
- result = self.cur.execute(query, params).fetchone()
- return result[0]
-
- query = f"SELECT * FROM messages WHERE remind_at='{date}'"
- result = self.cur.execute(query).fetchall()
- ret = [
- {
- "message": i[2],
- "user": __get_user_name(i[4]),
- "apparatnr": i[5],
- "id": i[0],
- }
- for i in result
- ]
- return ret
-
- def get_apparat_id(self, appname):
- query = f"SELECT appnr FROM semesterapparat WHERE name='{appname}'"
- result = self.cur.execute(query).fetchone()
- return result[0]
-
- def get_apparats_by_semester(self, semester: str):
- query = f"SELECT * FROM semesterapparat WHERE erstellsemester='{semester}'"
- result = self.cur.execute(query).fetchall()
- return result
-
- def get_semester(self) -> list[str]:
- query = "SELECT DISTINCT erstellsemester FROM semesterapparat"
- result = self.cur.execute(query).fetchall()
- return [i for i in result]
-
- def is_eternal(self, id):
- query = f"SELECT dauer FROM semesterapparat WHERE id={id}"
- result = self.cur.execute(query).fetchone()
- return result[0]
-
- def statistic_request(self, **kwargs: Any):
- def __query(query):
- result = self.cur.execute(query).fetchall()
- for result_a in result:
- orig_value = result_a
- prof_name = self.get_prof_name_by_id(result_a[2])
- # replace the prof_id with the prof_name
- result_a = list(result_a)
- result_a[2] = prof_name
- result_a = tuple(result_a)
- result[result.index(orig_value)] = result_a
-
- return result
-
- if "deletable" in kwargs.keys():
- query = f"SELECT * FROM semesterapparat WHERE deletion_status=0 AND dauer=0 AND (erstellsemester!='{kwargs['deletesemester']}' OR verlängerung_bis!='{kwargs['deletesemester']}')"
- return __query(query)
-
- if "dauer" in kwargs.keys():
- 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 {}:
- print(key, value)
- query += f"{key}='{value}' AND "
- print(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(
- f"deletesemester='{kwargs['deletesemester']}' AND ", ""
- )
- if "endsemester" in kwargs.keys():
- if "erstellsemester" in kwargs.keys():
- query = query.replace(f"endsemester='{kwargs['endsemester']}' AND ", "")
- query = query.replace(
- f"erstellsemester='{kwargs['erstellsemester']} AND ", "xyz"
- )
- else:
- query = query.replace(
- f"endsemester='{kwargs['endsemester']}' AND ", "xyz"
- )
- print("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
-
- query = query[:-5]
- print(query)
- return __query(query)
-
- def get_app_count_by_semester(self) -> tuple[list[str], list[int]]:
- """get the apparats created and deleted in the distinct semesters"""
-
- # get unique semesters
- query = "SELECT DISTINCT erstellsemester FROM semesterapparat"
- result = self.cur.execute(query).fetchall()
- semesters = [i[0] for i in result]
- created = []
- deleted = []
- for semester in semesters:
- query = f"SELECT COUNT(*) FROM semesterapparat WHERE erstellsemester='{semester}'"
- result = self.cur.execute(query).fetchone()
- created.append(result[0])
- query = f"SELECT COUNT(*) FROM semesterapparat WHERE deletion_status=1 AND deleted_date='{semester}'"
- result = self.cur.execute(query).fetchone()
- deleted.append(result[0])
- # store data in a tuple
- ret = []
- e_tuple = ()
- for sem in semesters:
- e_tuple = (
- sem,
- created[semesters.index(sem)],
- deleted[semesters.index(sem)],
- )
- ret.append(e_tuple)
- return ret
- # get the count of apparats created in the semesters
-
- def apparats_by_semester(self, semester: str):
- """Get a list of all created and deleted apparats in the given semester"""
- # get a list of apparats created and in the given semester
- query = f"SELECT name,prof_id FROM semesterapparat WHERE erstellsemester='{semester}'"
- result = self.cur.execute(query).fetchall()
- c_tmp = []
- for i in result:
- c_tmp.append((i[0], self.get_prof_name_by_id(i[1])))
- query = (
- f"SELECT name,prof_id FROM semesterapparat WHERE deleted_date='{semester}'"
- )
- result = self.cur.execute(query).fetchall()
- d_tmp = []
- for i in result:
- d_tmp.append((i[0], self.get_prof_name_by_id(i[1])))
- # group the apparats by prof
- c_ret = {}
- for i in c_tmp:
- if i[1] not in c_ret.keys():
- c_ret[i[1]] = [i[0]]
- else:
- c_ret[i[1]].append(i[0])
- d_ret = {}
- for i in d_tmp:
- if i[1] not in d_ret.keys():
- d_ret[i[1]] = [i[0]]
- else:
- d_ret[i[1]].append(i[0])
- return {"created": c_ret, "deleted": d_ret}
-
- def delete_message(self, message_id):
- query = "DELETE FROM messages WHERE id=?"
- params = (message_id,)
- self.cur.execute(query, params)
- self.database.commit()
-
- def delete_medium(self, title_id):
- # delete the bookdata from the media table
- query = "UPDATE media SET deleted=1 WHERE id=?"
- params = (title_id,)
- self.cur.execute(query, params)
- self.database.commit()
- pass
-
- def update_bookdata(self, bookdata: BookData, title_id):
- query = "UPDATE media SET bookdata=? WHERE id=?"
- converted = pickle.dumps(bookdata)
- params = (converted, title_id)
- self.cur.execute(query, params)
- self.database.commit()
-
- def get_specific_book(self, book_id):
- query = "SELECT bookdata FROM media WHERE id=?"
- params = (book_id,)
- result = self.cur.execute(query, params).fetchone()
- return pickle.loads(result[0])
-
- def get_media(self, app_id, prof_id, del_state=0) -> list[dict[int, BookData, int]]:
- """request media from database and return result as list.
-
- Args:
- ----
- - app_id (int): ID of the apparat
- - prof_id (int): ID of the prof
- - del_state (int, optional): If deleted books should be requested as well. 1 = yes 0 = no. Defaults to 0.
-
- Returns:
- -------
- - list[dict[int,BookData,int]]: Returns a list of dictionaries containing the bookdata, the id and the availability of the book in the following format:
- -------
- {"id": int,
- "bookdata": BookData,
- "available": int}
- """
- query = f"SELECT id,bookdata,available FROM media WHERE (app_id={app_id} AND prof_id={prof_id}) AND (deleted={del_state if del_state == 0 else '1 OR deleted=0'})"
- logger.log_info(f"Requesting media from database with query: {query}")
- result = self.cur.execute(query).fetchall()
- ret_result = []
- for result_a in result:
- # ic(result_a)
- data = {"id": int, "bookdata": BookData, "available": int}
- data["id"] = result_a[0]
- data["bookdata"] = pickle.loads(result_a[1])
- data["available"] = result_a[2]
- ret_result.append(data)
- return ret_result
-
- def get_subjects_and_aliases(self):
- query = "SELECT subjects.name, aliases.name FROM subjects LEFT JOIN aliases ON subjects.id = aliases.subject_id"
- return self.cur.execute(query).fetchall()
-
- def get_subjects(self):
- query = "SELECT id,name FROM subjects"
- return self.cur.execute(query).fetchall()
-
- def get_aliases(self, subject_id):
- query = f"SELECT name FROM aliases WHERE subject_id={subject_id}"
- return self.cur.execute(query).fetchall()
-
- def add_subject(self, subject_name):
- query = f"INSERT INTO subjects (name) VALUES ('{subject_name}')"
- self.cur.execute(query)
- self.database.commit()
-
- def get_apparats_by_prof(self, prof_id):
- query = f"SELECT * FROM semesterapparat WHERE prof_id={prof_id}"
- return self.cur.execute(query).fetchall()
-
- def add_alias(self, alias_name, subject):
- query = f"SELECT id FROM subjects WHERE name='{subject}'"
- subject_id = self.cur.execute(query).fetchone()[0]
- query = f"INSERT INTO aliases (name,subject_id) VALUES ('{alias_name}',{subject_id})"
- self.cur.execute(query)
- self.database.commit()
-
- def update_apparat(self, apparat_data: ApparatData):
- data = apparat_data
- query = "UPDATE semesterapparat SET name = ?, fach = ?, dauer = ?, prof_id = ? WHERE appnr = ?"
- params = (
- data.appname,
- data.app_fach,
- data.dauerapp,
- self.get_prof_id(data.profname),
- data.appnr,
- )
- print(query)
- self.cur.execute(query, params)
- self.database.commit()
-
- def delete_apparat(self, appnr: str, semester: str):
- # update the deletion status to 1 and the deleted_state to semester for the given apparat
- query = f"UPDATE semesterapparat SET deletion_status=1, deleted_date='{semester}' WHERE appnr='{appnr}'"
- self.cur.execute(query)
- self.database.commit()
-
- def get_book_id(self, bookdata: BookData, app_id: int, prof_id: int):
- query = "SELECT id FROM media WHERE bookdata=? AND app_id=? AND prof_id=?"
- params = (pickle.loads(bookdata), app_id, prof_id)
- result = self.cur.execute(query, params).fetchone()
- return result
-
- def set_availability(self, book_id, available):
- query = "UPDATE media SET available=? WHERE id=?"
- params = (available, book_id)
- self.cur.execute(query, params)
- self.database.commit()
-
- def get_latest_book_id(self):
- query = "SELECT id FROM media ORDER BY id DESC LIMIT 1"
- result = self.cur.execute(query).fetchone()
- return result[0]
-
- def close(self):
- self.database.close()
-
- def login(self, username, hashed_password) -> bool:
- # check if the user and password exist in the database
- # if yes, return True
- # if no, return False
- query = "SELECT salt FROM user WHERE username=?"
- params = (username,)
- result = self.cur.execute(query, params).fetchone()
-
- if result is None:
- return False
- salt = result[0]
- print(salt)
- query = "SELECT password FROM user WHERE username=?"
- params = (str(username),)
- result = self.cur.execute(query, params).fetchone()
- password = result[0]
- if password == f"{salt}{hashed_password}":
- return True
- else:
- return False
-
- # admin stuff below here
- def get_users(self):
- query = "SELECT * FROM user"
- return self.cur.execute(query).fetchall()
-
- def get_apparats(self) -> list[tuple]:
- query = "SELECT * FROM semesterapparat"
- return self.cur.execute(query).fetchall()
-
- def change_password(self, user, password):
- saltq = "SELECT salt FROM user WHERE username=?"
- params = (user,)
- salt = self.cur.execute(saltq, params).fetchone()[0]
- password = f"{salt}{password}"
- query = "UPDATE user SET password=? WHERE username=?"
- params = (password, user)
- self.cur.execute(query, params)
- self.database.commit()
-
- def get_role(self, username):
- query = "SELECT role FROM user WHERE username=?"
- params = (username,)
- result = self.cur.execute(query, params).fetchone()
- return result[0]
-
- def get_roles(self):
- query = "SELECT role FROM user"
- return self.cur.execute(query).fetchall()
-
- def create_user(self, username, password, role, salt):
- """Create a user based on passed data.
-
- Args:
- ----
- - username (str): Username to be used
- - password (str): the salted password
- - role (str): Role of the user
- - salt (str): a random salt for the user
- """
- query = "INSERT OR IGNORE INTO user (username, password, role, salt) VALUES (?, ?, ?, ?)"
- params = (username, password, role, salt)
- self.cur.execute(query, params)
- self.database.commit()
-
- def delete_user(self, user):
- query = "DELETE FROM user WHERE username=?"
- params = (user,)
- self.cur.execute(query, params)
- self.database.commit()
-
- def get_faculty_members(self, name: str = None):
- query = "SELECT titel, fname,lname,mail,telnr,fullname FROM prof"
- if name:
- query = query.replace(",fullname", "")
- query += f" WHERE fullname='{name}'"
- return self.cur.execute(query).fetchall()
-
- def update_faculty_member(self, data, oldlname, oldfname):
- placeholders = ", ".join(f"{k} = :{k}" for k in data.keys())
- sql = f"UPDATE prof SET {placeholders} WHERE lname = :oldlname AND fname = :oldfname"
- data["oldlname"] = oldlname
- data["oldfname"] = oldfname
- print(sql, data)
- self.cur.execute(sql, data)
- self.database.commit()
-
- def faculty_data(self, name):
- query = f"SELECT * FROM prof WHERE fullname='{name}'"
- result = self.cur.execute(query).fetchone()
- return result
-
- def update_user(self, username, data: dict[str, str]):
-
- query = "UPDATE user SET "
- for key, value in data.items():
- if key == "username":
- continue
- query += f"{key}='{value}',"
- query = query[:-1]
- query += " WHERE username=?"
- params = (username,)
-
- self.cur.execute(query, params)
- self.database.commit()
-
- def check_username(self, username):
- query = "SELECT username FROM user WHERE username=?"
- params = (username,)
- result = self.cur.execute(query, params).fetchone()
- if result is None:
- return False
- return True
-
- def get_apparats_name(self, app_id, prof_id):
- query = f"SELECT name FROM semesterapparat WHERE appnr={app_id} AND prof_id={prof_id}"
- # ic(query)
- result = self.cur.execute(query).fetchone()
- return result[0]
-
- def search_book(self, data: dict[str, str]) -> list[tuple[BookData, int]]:
- query = "SELECT * FROM media "
- result = self.database.execute(query).fetchall()
- ret = []
- # get length of data dict
- length = len(data)
- mode = 0
- if length == 1:
- if "signature" in data.keys():
- mode = 1
- elif "title" in data.keys():
- mode = 2
- elif length == 2:
- mode = 3
- else:
- return None
- print(len(result))
- for res in result:
- bookdata = pickle.loads(res[1])
- app_id = res[2]
- prof_id = res[3]
- # if signature and title present in dict:
- # if signature present in dict:
- if mode == 1:
- if data["signature"] in bookdata.signature:
- ret.append((bookdata, app_id, prof_id))
- # if title present in dict:
- elif mode == 2:
- if data["title"] in bookdata.title:
- ret.append((bookdata, app_id, prof_id))
- elif mode == 3:
- if (
- data["signature"] in bookdata.signature
- and data["title"] in bookdata.title
- ):
- ret.append((bookdata, app_id, prof_id))
- return ret
-
-
-if __name__ == "__main__":
- db = Database()
- print(db.login("kirchner", "loginpass"))
diff --git a/src/logic/userInterface.py b/src/logic/userInterface.py
deleted file mode 100644
index ef35d3d..0000000
--- a/src/logic/userInterface.py
+++ /dev/null
@@ -1,2453 +0,0 @@
-# encoding: utf-8
-import atexit
-import os
-
-# import re
-import sys
-import tempfile
-import time
-import webbrowser
-from pathlib import Path
-
-from icecream import ic
-from natsort import natsorted
-from omegaconf import OmegaConf
-from PyQt6 import QtCore, QtGui, QtWidgets
-from PyQt6.QtCore import QDate, QThread
-from PyQt6.QtGui import QColor, QRegularExpressionValidator
-
-from src.backend.admin_console import AdminCommands
-from src.backend.create_file import recreateElsaFile, recreateFile
-from src.backend.database import Database
-from src.backend.delete_temp_contents import delete_temp_contents
-from src.backend.semester import generateSemesterByDate
-from src.logic import AvailChecker, BookGrabber, c_sort
-from src.logic.constants import APP_NRS, PROF_TITLES
-from src.logic.csvparser import csv_to_list
-from src.logic.dataclass import ApparatData, BookData
-from src.logic.log import MyLogger
-from src.logic.wordparser import elsa_word_to_csv, word_docx_to_csv
-from src.ui import (
- App_Ext_Dialog,
- DataGraph,
- FilePicker,
- Mail_Dialog,
- StatusWidget,
- Ui_Semesterapparat,
- edit_bookdata_ui,
- login_ui,
- medienadder_ui,
- parsed_titles_ui,
- popus_confirm,
- reminder_ui,
- settings_ui,
-)
-from src.utils import Icon
-
-config = OmegaConf.load("config.yaml")
-
-
-class Medien(medienadder_ui):
- def __init__(self) -> None:
- self.logger = MyLogger("Medien")
- super().__init__()
- self.mode = ""
- self.data = []
-
- def get_list_data(self) -> list:
- signatures = self.listWidget.findItems("*", QtCore.Qt.MatchFlag.MatchWildcard)
- return [signature.text() for signature in signatures]
-
- def get_mode(self) -> str:
- return self.comboBox.currentText()
-
-
-class MyComboBox(QtWidgets.QComboBox):
-
- def __init__(self, parent=None):
- super().__init__(parent)
-
-
-valid_input = (0, 0, 0, 0, 0, 0)
-
-
-class MessageCalendar(QtWidgets.QCalendarWidget):
- # Widget for MessageCalendar
- def __init__(self, parent=None):
- super().__init__(parent)
- self.messages = {} # Dictionary to store dates with messages
-
- def setMessages(self, messages):
- for message in messages:
- print(message)
- # Convert the date string to a QDate object
- date = QDate.fromString(message["remind_at"], "yyyy-MM-dd")
- # Store the message for the date
- self.messages[date] = message["message"]
- self.updateCells()
-
- def updateCells(self):
- self.repaint()
-
- def paintCell(self, painter, rect, date):
- super().paintCell(painter, rect, date)
-
- # Check if there is a message for the current date
- if date in self.messages:
- # If there is a message, color the cell background
- painter.fillRect(rect, QColor("#a7e681"))
-
- def change_stylesheet_cell(self, date: QDate, color: str):
- # change the stylesheet of a cell
- self.setStyleSheet(
- f"QCalendarWidget QTableView QTableCornerButton::section {{background-color: {color};}}"
- )
-
-
-class Ui(Ui_Semesterapparat):
- # use the Ui_MainWindow class from mainwindow.py
- def __init__(self, MainWindow, username: str) -> None:
- self.logger = MyLogger("Ui")
- self.logger.log_info("Starting Semesterapparatsmanagement")
- super().__init__()
- self.active_user = username
- self.setupUi(MainWindow)
- self.MainWindow = MainWindow
- # set the window title
- MainWindow.setWindowTitle("Semesterapparatsmanagement")
- MainWindow.setWindowIcon(Icon("logo").icon)
-
- self.db = Database()
- # self.show()
- # self.setWindowTitle("Semesterapparatsmanagement")
- # self.setWindowIcon(QIcon("ui\icon.png"))
- # self.sem_sommer.clicked.connect(self.buttonClicked)
- self.btn_add_document.clicked.connect(self.add_document)
- self.check_file.clicked.connect(
- self.btn_check_file_threaded
- ) # default: self.add_media_from_file)
- self.create_new_app.clicked.connect(self.btn_create_new_apparat)
- # self.load_app.clicked.connect(self.btn_load_apparat)
- self.btn_apparat_save.clicked.connect(self.btn_save_apparat)
- self.btn_apparat_apply.clicked.connect(self.update_apparat)
- self.btn_open_document.clicked.connect(self.open_document)
- self.add_medium.clicked.connect(self.btn_add_medium)
- self.btn_copy_adis_command.clicked.connect(self.text_to_clipboard)
- self.btn_reserve.clicked.connect(self.check_availability)
- self.calendarWidget = MessageCalendar(self.frame_2)
- self.calendarWidget.setGeometry(QtCore.QRect(0, 0, 291, 191))
- self.calendarWidget.setGridVisible(True)
- self.calendarWidget.setVerticalHeaderFormat(
- QtWidgets.QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader
- )
- self.calendarWidget.setObjectName("MessageCalendar")
- self.calendarWidget.clicked.connect(self.open_reminder)
- # assign a context menu to the calendar
-
- self.tableWidget_apparat_media.horizontalHeader().setSectionResizeMode(
- QtWidgets.QHeaderView.ResizeMode.Stretch
- )
- self.tableWidget_apparate.horizontalHeader().setSectionResizeMode(
- QtWidgets.QHeaderView.ResizeMode.Stretch
- )
- self.tableWidget_apparate.setSortingEnabled(True)
-
- # Actions
- self.actionEinstellungen.triggered.connect(self.open_settings)
- self.actionDokumentation.triggered.connect(self.open_documentation)
- Icon("offAction", self.actionBeenden)
- self.actionBeenden.triggered.connect(self.quit)
- # set validators
- self.sem_year.setText(str(QtCore.QDate.currentDate().year()))
- self.prof_mail.setValidator(
- QRegularExpressionValidator(
- QtCore.QRegularExpression(
- r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}"
- )
- )
- )
- self.prof_tel_nr.setValidator(QtGui.QIntValidator())
- # set the validator for the app name, allow all letters and umlauts
- self.app_fach.setValidator(
- QtGui.QRegularExpressionValidator(
- QtCore.QRegularExpression(r"[a-zA-Z\s\W]+")
- )
- )
-
- # allow only letters, numbers, whitespaces, symbols for the apparat name
- self.app_name.setValidator(
- QtGui.QRegularExpressionValidator(
- QtCore.QRegularExpression(r"[a-zA-Z0-9\s\W]+")
- )
- )
- self.tableWidget_apparate.addScrollBarWidget(
- QtWidgets.QScrollBar(), QtCore.Qt.AlignmentFlag.AlignRight
- )
- # connect contextmenuevent to tablewidget
-
- # enable automatic resizing of columns for book_search_result
- self.book_search_result.horizontalHeader().setSectionResizeMode(
- QtWidgets.QHeaderView.ResizeMode.Stretch
- )
- self.tableWidget_apparate.doubleClicked.connect(self.load_app_data)
- self.load_app.hide()
- print(f"user:{self.active_user}")
- userrole = self.db.getRole(self.active_user)
- # hide admin interface when non-admin is logged in
- if userrole == "admin":
- self.tabWidget.setTabVisible(3, True)
- else:
- self.tabWidget.setTabVisible(3, False)
- # self.update_app_media_list()
- self.populate_prof_dropdown()
- self.populate_appfach_dropdown()
- # if the focus is changed from the prof name dropdown, set the prof data if the prof exists in the database, otherwise show a message
- self.drpdwn_prof_name.currentIndexChanged.connect(self.set_prof_data)
- self.cancel_active_selection.clicked.connect(self.btn_cancel_active_selection)
- self.check_eternal_app.stateChanged.connect(self.set_state)
- # validate inputs
- 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)
- self.app_name.textChanged.connect(self.validate_app_name)
- self.app_fach.currentTextChanged.connect(self.validate_app_fach)
- self.sem_year.textChanged.connect(self.validate_semester)
- self.check_eternal_app.stateChanged.connect(self.validate_semester)
- self.chkbx_show_del_media.stateChanged.connect(self.update_app_media_list)
-
- self.progress_label.setText("Bitte warten...")
-
- # Set visibility/enabled state of certain entries
- self.chkbx_show_del_media.setEnabled(False)
- self.label_info.hide()
- self.app_group_box.setEnabled(False)
- self.line_2.hide()
- self.progress_label.hide()
- self.message_frame.hide()
- self.btn_reserve.hide()
- self.label_20.hide()
- self.line_3.hide()
- self.avail_status.hide()
- self.chkbx_show_del_media.hide()
- self.groupBox_2.hide()
- self.groupBox.hide()
- self.btn_del_select_apparats.setEnabled(False)
-
- self.check_deletable.stateChanged.connect(self.gridchange)
- self.tableWidget.horizontalHeader().setSectionResizeMode(
- QtWidgets.QHeaderView.ResizeMode.Stretch
- )
- self.btn_del_select_apparats.clicked.connect(self.delete_selected_apparats)
- self.statistics_table.doubleClicked.connect(self.display_detailed_data)
- self.tabWidget_2.currentChanged.connect(self.tabW2_changed)
- self.tabWidget.currentChanged.connect(self.tabW1_changed)
- self.tableWidget.resizeColumnsToContents()
- self.tableWidget.resizeRowsToContents()
-
- # create a thread, that continually checks the validity of the inputs
- self.validate_thread = QThread()
- self.validate_thread.started.connect(self.thread_check)
- self.validate_thread.start()
-
- # get all current apparats and cache them in a list
- self.apparats = self.get_apparats()
-
- self.old_apparats = self.apparats # create a clone to compare against later
- # if length of apparats changes, update box_apparats
- # if tab is changed, gather data needed
- self.tabWidget.currentChanged.connect(self.tab_changed)
- self.btn_search.clicked.connect(self.statistics)
-
- ### Admin interface ###
- self.select_action_box.addItem("")
- self.select_action_box.setCurrentText("")
- self.hide_all()
- self.select_action_box.currentTextChanged.connect(self.admin_action_changed)
- self.edit_faculty_member_select_member.currentTextChanged.connect(
- self.edit_faculty_member_set_data
- )
- self.book_search.clicked.connect(self.search_book)
-
- # Context Menus
- self.tableWidget_apparate.setContextMenuPolicy(
- QtCore.Qt.ContextMenuPolicy.CustomContextMenu
- )
- self.tableWidget_apparat_media.setContextMenuPolicy(
- QtCore.Qt.ContextMenuPolicy.CustomContextMenu
- )
- self.tableWidget_apparate.customContextMenuRequested.connect(
- self.open_context_menu
- )
- self.tableWidget_apparat_media.customContextMenuRequested.connect(
- self.media_context_menu
- )
- self.tableWidget.customContextMenuRequested.connect(
- self.statistics_table_context_menu
- )
- # statistic side buttons
- self.btn_notify_for_deletion.clicked.connect(self.notify_for_deletion)
- self.btn_notify_for_deletion.setEnabled(False)
- # elsa buttons
- self.elsa_add_new.clicked.connect(self.add_new_elsa)
- self.elsa_cancel_create.clicked.connect(self.cancel_elsa_creation)
- self.elsa_save.clicked.connect(self.save_elsa)
- self.elsa_date_today.clicked.connect(self.generateTodayDateElsa)
- self.active_semester.clicked.connect(self.addSemester)
- Icon("semester", self.active_semester)
- Icon("today", self.elsa_date_today)
- self.elsa_table.doubleClicked.connect(self.open_elsa)
- self.btn_add_document_elsa.clicked.connect(self.addDokumentElsa)
- self.check_file_elsa.clicked.connect(self.parseDokumentElsa)
- self.btn_open_document_elsa.clicked.connect(self.openDocumentElsa)
-
- # admin buttons
- self.user_frame_addUser.clicked.connect(self.add_user)
- self.pushButton.clicked.connect(self.delete_user)
- self.update_user.clicked.connect(self.update_user_data)
- self.update_faculty_member.clicked.connect(self.edit_faculty_member_action)
-
- # Create instances to be used by the threads in the application
- self.bookGrabber = None
- self.availChecker = None
- self.mail_thread = None
- self.autoGrabber = None
-
- def quit(self):
- # delete all temporary files
- delete_temp_contents()
- sys.exit()
-
- def add_new_elsa(self):
- self.create_frame_elsa.setEnabled(True)
- self.elsa_cancel_create.setEnabled(True)
- self.active_semester.setEnabled(True)
- profs = self.db.getProfs()
- for prof in profs:
- self.elsa_prof.addItem(f"{prof[3]}, {prof[2]}")
- self.elsa_prof.setCurrentText("")
- self.elsa_date.setText("")
- self.elsa_semester.setText("")
-
- def cancel_elsa_creation(self):
- self.create_frame_elsa.setEnabled(False)
- self.elsa_cancel_create.setEnabled(False)
- self.elsa_prof.setCurrentText("")
- self.elsa_date.setText("")
- self.elsa_semester.setText("")
- self.dokument_list_elsa.setRowCount(0)
- self.table_elsa_list.setRowCount(0)
-
- def generateTodayDateElsa(self):
- self.elsa_date.setText(QDate.currentDate().toString("dd.MM.yyyy"))
-
- def addSemester(self):
- self.elsa_semester.setText(self.generateSemester(today=True))
-
- def save_elsa(self):
- if (
- self.elsa_prof.currentText() == ""
- or self.elsa_semester.text() == ""
- or self.elsa_date.text() == ""
- ):
- # warning message
- self.confirm_popup("Bitte füllen Sie alle Felder aus")
-
- return
- prof = self.elsa_prof.currentText()
- semester = self.elsa_semester.text()
- date = self.elsa_date.text()
-
- self.db.createElsaApparat(date, prof, semester)
- self.cancel_elsa_creation()
-
- def insert_elsa_into_table(self, apparat):
- self.elsa_table.insertRow(0)
- date = apparat[1]
- semester = apparat[2]
- prof = apparat[3]
- self.elsa_table.setItem(0, 0, QtWidgets.QTableWidgetItem(prof))
- self.elsa_table.setItem(0, 1, QtWidgets.QTableWidgetItem(date))
- self.elsa_table.setItem(0, 2, QtWidgets.QTableWidgetItem(semester))
- return (semester, 1)
-
- def open_elsa(self):
- prof = self.elsa_table.item(self.elsa_table.currentRow(), 0).text()
- date = self.elsa_table.item(self.elsa_table.currentRow(), 1).text()
- semester = self.elsa_table.item(self.elsa_table.currentRow(), 2).text()
- if self.elsa_prof.currentText() == prof:
- self.logger.log_info("Same prof, stopping")
- return
-
- self.dokument_list_elsa.setRowCount(0)
- self.table_elsa_list.setRowCount(0)
- self.elsa_cancel_create.setEnabled(True)
- # get elsa apparats, iterate over them and find the one where all matches
- elsa_apparats = self.db.getElsaApparats()
- elsa_id = None
- for apparat in elsa_apparats:
- if apparat[1] == date and apparat[2] == semester and apparat[3] == prof:
- elsa_id = apparat[0]
- print(elsa_id)
- break
- if elsa_id is None:
- return
- self.elsa_date.setText(date)
- self.elsa_semester.setText(semester)
- self.elsa_prof.setCurrentText(prof)
- documents = self.db.getElsaFiles(elsa_id)
- for document in documents:
- print(document)
- self.dokument_list_elsa.insertRow(0)
- self.dokument_list_elsa.setItem(
- 0, 0, QtWidgets.QTableWidgetItem(document[0])
- )
- self.dokument_list_elsa.setItem(
- 0, 1, QtWidgets.QTableWidgetItem(document[1])
- )
- self.dokument_list_elsa.setItem(0, 2, QtWidgets.QTableWidgetItem("❌"))
- self.dokument_list_elsa.setItem(
- 0, 3, QtWidgets.QTableWidgetItem("Database")
- )
- scans = self.db.getElsaMedia(elsa_id)
- if scans == []:
- self.create_frame_elsa.setEnabled(True)
- else:
- for scan in scans:
- self.table_elsa_list.insertRow(0)
- self.table_elsa_list.setItem(0, 0, QtWidgets.QTableWidgetItem(scan[1]))
- self.table_elsa_list.setItem(0, 1, QtWidgets.QTableWidgetItem(scan[2]))
- self.table_elsa_list.setItem(0, 2, QtWidgets.QTableWidgetItem(scan[3]))
- self.table_elsa_list.setItem(0, 3, QtWidgets.QTableWidgetItem(scan[4]))
-
- def addDokumentElsa(self):
- print("Add document")
- picker = FilePicker()
- files = picker.pick_files()
- datalist = []
- for file in files:
- data = {}
- print(file)
- filename = file.split("/")[-1]
- filetype = filename.split(".")[-1]
- self.dokument_list_elsa.insertRow(0)
- self.dokument_list_elsa.setItem(0, 0, QtWidgets.QTableWidgetItem(filename))
- self.dokument_list_elsa.setItem(0, 1, QtWidgets.QTableWidgetItem(filetype))
- self.dokument_list_elsa.setItem(0, 2, QtWidgets.QTableWidgetItem("*"))
- self.dokument_list_elsa.setItem(0, 3, QtWidgets.QTableWidgetItem(file))
- # set tooltip of row 3 to the file path for each row
- self.dokument_list_elsa.item(0, 3).setToolTip(file)
- data["name"] = filename
- data["path"] = file
- data["type"] = filetype
- datalist.append(data)
- elsa_id = self.db.getElsaId(
- self.elsa_prof.currentText(),
- self.elsa_semester.text(),
- self.elsa_date.text(),
- )
- print(elsa_id)
- if elsa_id is None:
- # get length of elsa table
- rows = self.elsa_table.rowCount()
- elsa_id = rows + 1
- self.db.insertElsaFile(datalist, elsa_id)
- self.elsa_save.click()
-
- def parseDokumentElsa(self):
- if self.dokument_list_elsa.rowCount() == 0:
- return
- else:
- # get the file path of the selected file based on it's row
- row = self.dokument_list_elsa.currentRow()
- file = self.dokument_list_elsa.item(row, 3).text()
- print(file)
- if file == "Database":
- filename = self.dokument_list_elsa.item(row, 0).text()
- filetype = self.dokument_list_elsa.item(row, 1).text()
-
- file = recreateElsaFile(
- filename=filename, filetype=filetype, open=False
- )
- print(file)
- data = elsa_word_to_csv(file)
- for row in data:
- self.table_elsa_list.insertRow(0)
- ic(row)
- chapter_title = row[2]
- book_title = row[4]
- signature = row[7]
- pages = row[6]
- data = {
- "chapter": chapter_title,
- "title": book_title,
- "signature": signature,
- "pages": pages,
- }
- self.table_elsa_list.setItem(
- 0, 0, QtWidgets.QTableWidgetItem(chapter_title)
- )
- self.table_elsa_list.setItem(
- 0, 1, QtWidgets.QTableWidgetItem(book_title)
- )
- self.table_elsa_list.setItem(
- 0, 2, QtWidgets.QTableWidgetItem(signature)
- )
- self.table_elsa_list.setItem(0, 3, QtWidgets.QTableWidgetItem(pages))
- self.db.addElsaMedia(
- data,
- self.db.getElsaId(
- self.elsa_prof.currentText(),
- self.elsa_semester.text(),
- self.elsa_date.text(),
- ),
- )
-
- def openDocumentElsa(self):
- # open the selected document
- row = self.dokument_list_elsa.currentRow()
- location = self.dokument_list_elsa.item(row, 3).text()
- filetype = self.dokument_list_elsa.item(row, 1).text()
- filename = self.dokument_list_elsa.item(row, 0).text()
- if location == "Database":
- recreateElsaFile(filename, filetype, open=True)
- else:
- os.system(f"{filename}")
-
- def notify_for_deletion(self):
- # get all selected apparats
- selected_apparats: list[dict] = []
- for i in range(self.tableWidget.rowCount()):
- data = {}
- if self.tableWidget.cellWidget(i, 0).isChecked():
- data["app_id"] = self.tableWidget.item(i, 2).text()
- data["app_name"] = self.tableWidget.item(i, 1).text()
- data["prof_name"] = self.tableWidget.item(i, 3).text()
-
- selected_apparats.append(data)
- # delete all selected apparats
- ic(selected_apparats)
- dialogs = []
- for i in selected_apparats:
-
- app_id = i["app_id"]
- app_name = i["app_name"]
- prof_name = i["prof_name"]
- prof_mail = self.db.getProfData(prof_name)[0]
- self.mail_thread = Mail_Dialog(
- app_id=app_id,
- app_name=app_name,
- prof_name=prof_name,
- prof_mail=prof_mail,
- app_subject="",
- default_mail="Information bezüglich der Auflösung des Semesterapparates",
- )
- dialogs.append(self.mail_thread)
- for dialog in dialogs:
- dialog.exec()
-
- self.btn_notify_for_deletion.setEnabled(False)
-
- def setStatisticTableSize(self):
- print(self.statistics_table.size(), self.statistics_table.rowCount())
- size = self.statistics_table.size()
- h = size.height()
- w = size.width()
- rows = self.statistics_table.rowCount()
- rowheight = round(h / rows) - 5
- header_width = round(w / 3) - 5
- for i in range(3):
- self.statistics_table.setColumnWidth(i, header_width)
- for i in range(rows):
- self.statistics_table.setRowHeight(i, rowheight)
-
- def get_apparats(self):
- alist = self.db.getAllAparats(deleted=0)
- alist = natsorted(alist, key=lambda x: x[4], reverse=True)
- for apparat in alist:
- self.insert_apparat_into_table(apparat)
-
- def populate_appfach_dropdown(self):
- self.app_fach.clear()
- self.app_fach.addItem("")
- self.app_fach.setCurrentText("")
- self.app_fach.addItems([subject[1] for subject in self.db.getSubjects()])
-
- def open_documentation(self):
- # open the documentation in the default browser
- webbrowser.open("file:///" + os.path.abspath("docs/index.html"))
- # documentation = documentationview.DocumentationViewer()
- # documentation.show()
-
- def tabW1_changed(self):
- if self.tabWidget.currentIndex() == 1: # Statistic
- # self.tabWidget.setCurrentIndex(1)
- self.tabWidget_2.setCurrentIndex(1)
- self.tabWidget_2.setCurrentIndex(0)
- self.populate_tab()
- if self.tabWidget.currentIndex() == 0: # Apparate
- # clear all entries from the table
- self.tableWidget_apparate.setRowCount(0)
- self.get_apparats()
- if self.tabWidget.currentIndex() == 2: # Elsa
- self.elsa_cancel_create.click()
- try:
- self.elsa_statistics.removeTab(1)
- except:
- pass
- self.elsa_table.setRowCount(0)
- elsa_apparats = self.db.getElsaApparats()
- elsa_apparats = natsorted(elsa_apparats, key=lambda x: x[2], reverse=True)
- graph_data = {"x": [], "y": []} # x = semester, y = number of apparats
-
- for apparat in elsa_apparats:
- print(apparat)
- data = self.insert_elsa_into_table(apparat)
- semester = data[0]
- number = data[1]
- if semester not in graph_data["x"]:
- graph_data["x"].append(semester)
- graph_data["y"].append(number)
- else:
- index = graph_data["x"].index(semester)
- graph_data["y"][index] += number
-
- generateMissing = True if len(graph_data["x"]) > 1 else False
- graph = DataGraph(
- "ELSA Apparate pro Semester",
- graph_data,
- generateMissing,
- "Anzahl der Apparate",
- )
- ic(graph_data)
- self.elsa_statistics_table.setRowCount(0)
- for i in range(len(graph_data["x"])):
- self.elsa_statistics_table.insertRow(0)
- self.elsa_statistics_table.setItem(
- 0, 0, QtWidgets.QTableWidgetItem(graph_data["x"][i])
- )
- self.elsa_statistics_table.setItem(
- 0, 1, QtWidgets.QTableWidgetItem(str(graph_data["y"][i]))
- )
- self.elsa_statistics.addTab(graph, "Graph")
-
- def search_book(self):
- self.book_search_result.setRowCount(0)
- signature = self.seach_by_signature.text()
- title = self.search_by_title.text()
- params = {
- "signature": signature if signature != "" else None,
- "title": title if title != "" else None,
- }
- params = {key: value for key, value in params.items() if value is not None}
- # ic(params)
- retdata = self.db.searchBook(params)
- if retdata is None:
- return
- for book in retdata:
-
- self.book_search_result.insertRow(0)
- self.book_search_result.setItem(
- 0, 0, QtWidgets.QTableWidgetItem(book[0].title)
- )
- self.book_search_result.setItem(
- 0, 1, QtWidgets.QTableWidgetItem(book[0].signature)
- )
- print(book[1])
- self.book_search_result.setItem(
- 0,
- 2,
- QtWidgets.QTableWidgetItem(self.db.getApparatName(book[1], book[2])),
- )
-
- def edit_faculty_member_set_data(self):
- # get the selected member
- name = self.edit_faculty_member_select_member.currentText()
- fullname = name.replace(",", "")
- print(fullname, name)
- # get the data for the selected member
- data = self.db.getProfByName(fullname)
- # set the data
- print(data)
- if data is None:
- self.edit_faculty_member_title.setText("")
- self.faculty_member_old_telnr.setText("")
- self.faculty_member_oldmail.setText("")
- self.edit_faculty_member_title.setText("")
- else:
- self.edit_faculty_member_title.setText(data[1])
- self.faculty_member_old_telnr.setText(data[6])
- self.faculty_member_oldmail.setText(data[5])
- (
- self.edit_faculty_member_title.setText(data[1])
- if data[1] is not None
- else self.edit_faculty_member_title.setText("")
- )
-
- # self.edit_faculty_member_name.setText(f"{data[3]} {data[2]}")
- # self.edit_faculty_member_title.setCurrentText(data[1])
- # self.edit_faculty_member_mail.setText(data[4])
- # self.edit_faculty_member_tel.setText(data[5])
- # self.edit_faculty_member_adis_id.setText(str(data[0]))
- # self.edit_faculty_member_id.setText(str(data[6]))
-
- def add_user(self):
- username = self.user_create_frame_username.text()
- password = self.user_create_frame_password.text()
- role = self.user_frame_userrole.currentText()
- if self.db.checkUsername(username):
- # ic("username already exists")
- # self.user_create_frame_error.setText("Der Nutzername ist bereits vergeben")#TODO: implement error message
- return
- userdata = AdminCommands().create_password(password)
- self.db.createUser(
- user=username,
- password=f"{userdata[1]}{userdata[0]}",
- salt=userdata[1],
- role=role,
- )
- self.user_create_frame_username.clear()
- self.user_create_frame_password.clear()
- self.user_frame_userrole.setCurrentText("")
- self.admin_action_changed()
-
- def delete_user(self):
- if self.user_delete_confirm.isChecked():
- username = self.user_delete_frame_user_select.currentText()
- self.db.deleteUser(username)
- self.user_delete_frame_user_select.removeItem(
- self.user_delete_frame_user_select.currentIndex()
- )
- self.user_delete_confirm.setChecked(False)
- else:
- self.user_delete_err_message.setText(
- "Bitte bestätigen Sie die Löschung des Nutzers"
- ) # TODO: implement error message
- # ic("please confirm the deletion of the user")
-
- def update_user_data(self):
- username = self.user_edit_frame_user_select.currentText()
- password = (
- self.user_edit_frame_new_password.text()
- if self.user_edit_frame_new_password.text() != ""
- else None
- )
- role = (
- self.user_edit_frame_role_select.currentText()
- if self.user_edit_frame_role_select.currentText() != ""
- else None
- )
-
- userdata = AdminCommands().create_password(password)
- data = {
- "password": f"{userdata[1]}{userdata[0]}",
- "salt": userdata[1],
- "role": role,
- }
- data = {key: value for key, value in data.items() if value is not None}
- print(data)
- self.db.updateUser(username=username, data=data)
- self.user_edit_frame_user_select.setCurrentText("")
- self.user_edit_frame_new_password.clear()
- self.user_edit_frame_role_select.setCurrentText("")
-
- def edit_faculty_member_action(self):
- def __gen_fullname(fname, lname, data):
- if fname == "" and lname == "":
- return data[3]
- if fname == "" and lname != "":
- return f"{lname} {data[1]}"
- if fname != "" and lname == "":
- return f"{data[2]} {fname}"
- if fname != "" and lname != "":
- return f"{lname} {fname}"
-
- # get the data and use new value if it is not none and does not mach the old value
- if self.edit_faculty_member_select_member.currentText() == "":
- return
- olddata = self.db.getFacultyMember(
- self.edit_faculty_member_select_member.currentText()
- )
- ic(olddata)
- data = olddata
- oldlname = data[2]
- oldfname = data[1]
- # take data except first and last entry
-
- titel = (
- self.edit_faculty_member_new_title.currentText()
- if self.edit_faculty_member_new_title.currentText() != "Kein Titel"
- else None
- )
- fname = (
- self.edit_faculty_member_new_surname.text()
- if self.edit_faculty_member_new_surname.text() != ""
- else self.edit_faculty_member_select_member.currentText()
- .split(" ")[1]
- .strip()
- )
- lname = (
- self.user_faculty_member_new_name.text()
- if self.user_faculty_member_new_name.text() != ""
- else self.edit_faculty_member_select_member.currentText()
- .split(" ")[0]
- .strip()
- )
- fullname = __gen_fullname(fname, lname, data)
- telnr = self.user_faculty_member_new_telnr.text()
- mail = self.user_faculty_member_new_mail.text()
- new_data = {
- "titel": titel,
- "fname": fname,
- "lname": lname,
- "fullname": fullname,
- "mail": mail,
- "telnr": telnr,
- }
- new_data = {key: value for key, value in new_data.items() if value != ""}
- self.db.updateFacultyMember(data=new_data, oldlname=oldlname, oldfname=oldfname)
- self.add_faculty_member_data()
- self.edit_faculty_member_new_title.setCurrentText("")
- self.edit_faculty_member_new_surname.clear()
- self.user_faculty_member_new_name.clear()
- self.user_faculty_member_new_telnr.clear()
- self.user_faculty_member_new_mail.clear()
-
- def hide_all(self):
- self.user_create_frame.hide()
- self.user_edit_frame.hide()
- self.user_delete_frame.hide()
- self.edit_faculty_member.hide()
-
- def admin_action_changed(self):
- action = self.select_action_box.currentText()
- roles = self.db.getRoles()
- roles = [role[0] for role in roles]
- # remove duplicates
- roles = list(dict.fromkeys(roles))
- users = self.db.getUsers()
- users = [user[2] for user in users]
- users.remove(self.active_user)
- if "admin" in users:
- users.remove("admin")
- if action == "Nutzer anlegen":
- self.hide_all()
- self.user_create_frame.show()
- self.user_frame_userrole.addItems(roles)
- elif action == "Nutzer aktualisieren":
- self.hide_all()
- self.user_edit_frame.show()
- self.user_edit_frame_role_select.addItems(roles)
- self.user_edit_frame_user_select.addItems(users)
- elif action == "Nutzer löschen":
- self.hide_all()
- self.user_delete_frame.show()
- self.user_delete_frame_user_select.addItems(users)
- self.user_delete_frame_user_select.setCurrentText("")
- self.user_delete_frame_user_select.addItems(users)
-
- elif action == "Lehrperson bearbeiten":
- self.hide_all()
- self.edit_faculty_member.show()
- self.add_faculty_member_data()
- self.edit_faculty_member_new_title.addItems(PROF_TITLES)
-
- else:
- self.hide_all()
- return
-
- def add_faculty_member_data(self):
- faculty_members = self.db.getFacultyMembers()
- names = [f"{member[5]}" for member in faculty_members]
- self.edit_faculty_member_select_member.clear()
- self.edit_faculty_member_select_member.addItems(names)
- self.edit_faculty_member_select_member.addItem("")
- self.edit_faculty_member_select_member.setCurrentText("")
-
- def tabW2_changed(self):
-
- if self.tabWidget_2.currentIndex() == 0:
- self.stackedWidget_4.setCurrentIndex(0)
- else:
- self.stackedWidget_4.setCurrentIndex(1)
-
- def generateSemester(self, today=False):
- """Generates the current semester.
-
- Args:
- -----
- today (bool, optional): If True, the current semester is generated. Defaults to False.
- Returns:
- --------
- str: The current semester
- """
- if today:
- return generateSemesterByDate()
- currentYear = self.sem_year.text()
- currentYear = int(currentYear[-2:])
-
- semester = (
- self.sem_sommer.text()
- if self.sem_sommer.isChecked()
- else self.sem_winter.text()
- )
- if semester == "Sommer":
- return "SoSe " + str(currentYear)
- else:
- return f"WiSe {currentYear}/{currentYear+1}"
-
- def display_detailed_data(self):
- selected_semester = self.statistics_table.item(
- self.statistics_table.currentRow(), 0
- ).text()
- # get all apparats from the selected semester
- data = self.db.getApparatsBySemester(selected_semester)
- # replace keys for german names
- # split to two lists
- created = {"Erstellt": data["created"]}
- deleted = {"Gelöscht": data["deleted"]}
- created_status = StatusWidget(created, selected_semester)
- deleted_status = StatusWidget(deleted, selected_semester)
- created_status.setSizePolicy(
- QtWidgets.QSizePolicy.Policy.Expanding,
- QtWidgets.QSizePolicy.Policy.Expanding,
- )
- deleted_status.setSizePolicy(
- QtWidgets.QSizePolicy.Policy.Expanding,
- QtWidgets.QSizePolicy.Policy.Expanding,
- )
-
- # add them to the gridLayout_4
- self.gridLayout_4.addWidget(created_status, 1, 0)
- self.gridLayout_4.addWidget(deleted_status, 1, 1)
- # self.setStatisticTableSize()
- created_status.person_double_clicked.connect(self.open_apparat)
- created_status.setToolTip("Doppelklick um den Semesterapparat zu öffnen")
- deleted_status.setToolTip("Nur zur Übersicht")
- # set deleted_status background to slightly gray
-
- def open_apparat(self, header: str, apparat: str, parent_depth: int):
- print(header)
- if header == "deleted" and parent_depth == 2:
- # TODO: warn message here
- print("warning")
- if parent_depth == 1:
- print(apparat)
- # person selected case - open all apparats from this person in the tableWidget
- self.tableWidget.setRowCount(0)
- prof_id = self.db.getProfId(apparat.split("(")[0].strip())
- apparats = self.db.getApparatsByProf(prof_id)
- for app in apparats:
- print(app)
- # set the items 0 = clickable checkbox, 1 = appname, 2 = profname, 3 = fach
- # insert new row
- self.tableWidget.insertRow(0)
- self.tableWidget.setItem(0, 0, QtWidgets.QTableWidgetItem(""))
- self.tableWidget.setItem(0, 1, QtWidgets.QTableWidgetItem(app[1]))
- self.tableWidget.setItem(0, 2, QtWidgets.QTableWidgetItem(str(app[4])))
- self.tableWidget.setItem(0, 3, QtWidgets.QTableWidgetItem(app[2]))
- self.tableWidget.setItem(0, 4, QtWidgets.QTableWidgetItem(app[3]))
- # replace the 0 with a checkbox
- checkbox = QtWidgets.QCheckBox()
- checkbox.setChecked(False)
- self.tableWidget.setCellWidget(0, 0, checkbox)
- # if i[9] is 1, set the background of the row to red
- if int(app[9]) == 1:
- for j in range(5):
- self.tableWidget.item(0, j).setBackground(
- QtGui.QColor(235, 74, 71)
- )
- # disable the checkbox
- self.tableWidget.cellWidget(0, 0).setEnabled(False)
- # set the tooltip
- self.tableWidget.cellWidget(0, 0).setToolTip(
- "Dieser Semesterapparat kann nicht gelöscht werden, da er bereits gelöscht wurde"
- )
- elif parent_depth == 2:
- # apparat selected case - open the apparat in the frame
- self.load_app_data(apparat)
- # change tab focus to tab 0
- self.tabWidget.setCurrentIndex(0)
- return
-
- def gridchange(self):
- if self.check_deletable.isChecked():
- self.box_semester.setEnabled(False)
- self.box_semester.clear()
- self.box_appnrs.setEnabled(False)
- self.box_appnrs.clear()
- self.box_person.setEnabled(False)
- self.box_person.clear()
- self.box_fach.setEnabled(False)
- self.box_fach.clear()
- self.box_erstellsemester.setEnabled(False)
- self.box_erstellsemester.clear()
- self.box_dauerapp.setEnabled(False)
- self.box_dauerapp.clear()
- else:
- self.box_semester.setEnabled(True)
- self.box_appnrs.setEnabled(True)
- self.box_person.setEnabled(True)
- self.box_fach.setEnabled(True)
- self.box_erstellsemester.setEnabled(True)
- self.box_dauerapp.setEnabled(True)
- self.tab_changed()
-
- def populate_tab(self):
- # add default values to the dropdowns
- self.box_appnrs.clear()
- self.box_appnrs.addItem("")
- self.box_appnrs.setCurrentText("")
- self.box_person.clear()
- self.box_person.addItem("")
- self.box_person.setCurrentText("")
- self.box_fach.clear()
- self.box_fach.addItem("")
- self.box_fach.setCurrentText("")
- self.box_erstellsemester.clear()
- self.box_erstellsemester.addItem("")
- self.box_erstellsemester.setCurrentText("")
- self.box_semester.clear()
- self.box_semester.addItem("")
- self.box_semester.setCurrentText("")
- self.box_dauerapp.clear()
- self.box_dauerapp.addItems(["Ja", "Nein", ""])
- self.box_dauerapp.setCurrentText("")
- # add custom vaules
- appnrs = self.db.getUnavailableApparatNumbers()
- apparats = natsorted(appnrs)
- apparats = [str(apparat) for apparat in apparats]
- self.box_appnrs.addItems(apparats)
- persons = self.db.getProfs()
- self.box_person.addItems([f"{person[3]}, {person[2]}" for person in persons])
- self.box_fach.addItems(subject[1] for subject in self.db.getSubjects())
- semester = self.db.getSemersters()
- self.box_erstellsemester.addItems(semester)
- self.statistics_table.setRowCount(0)
-
- # set data for table and graph in tab 2 tableWidget_3
- data = self.db.getApparatCountBySemester()
- data = c_sort.custom_sort(data)
- # self.tabWidget_3.clear()
- self.tabWidget_3.removeTab(1)
- self.statistics_table.setRowCount(len(data))
- for i in range(len(data)):
- self.statistics_table.setItem(i, 0, QtWidgets.QTableWidgetItem(data[i][0]))
- self.statistics_table.setItem(
- i, 1, QtWidgets.QTableWidgetItem(str(data[i][1]))
- )
- self.statistics_table.setItem(
- i, 2, QtWidgets.QTableWidgetItem(str(data[i][2]))
- )
- self.statistics_table.resizeColumnsToContents()
- self.statistics_table.resizeRowsToContents()
- # self.setStatisticTableSize()
-
- # get height of the table
- # create graph
-
- graph_data = {
- "x": [i[0] for i in data],
- "y": {"Erstellt": [i[1] for i in data], "Gelöscht": [i[2] for i in data]},
- }
- graph = DataGraph(title="Erstellte und gelöschte Apparate", data=graph_data)
-
- # place the graph into tabWidget_3
- self.tabWidget_3.addTab(graph, "Graph")
- self.tabWidget_3.setCurrentIndex(0)
-
- def tab_changed(self):
- curr_tab = self.tabWidget.currentIndex()
- if curr_tab == 0: # create tab
- return
- elif curr_tab == 1: # statistics tab
- self.populate_tab()
-
- def populate_dropdown(self, box, data):
- box.clear()
- box.addItem("")
- box.setCurrentText("")
- box.addItems(data)
-
- def delete_selected_apparats(self):
- # get all selected apparats
- selected_apparats = []
- selected_apparat_rows = []
- for i in range(self.tableWidget.rowCount()):
- if self.tableWidget.cellWidget(i, 0).isChecked():
- selected_apparats.append(self.tableWidget.item(i, 2).text())
- selected_apparat_rows.append(i)
- # delete all selected apparats
- print(selected_apparats)
- for apparat in selected_apparats:
- self.db.deleteApparat(apparat, self.generateSemester(today=True))
- for row in selected_apparat_rows:
- # set the background of the row to red
- for j in range(5):
- self.tableWidget.item(row, j).setBackground(QtGui.QColor(235, 74, 71))
- # refresh the table
- self.populate_tab()
- self.btn_del_select_apparats.setEnabled(False)
-
- def statistics(self):
- """Generate the statistics based on the selected filters."""
- self.db_err_message.setText("")
- self.btn_del_select_apparats.setEnabled(True)
- self.btn_notify_for_deletion.setEnabled(True)
- params = {
- "appnr": (
- self.box_appnrs.currentText()
- if self.box_appnrs.currentText() != ""
- else None
- ),
- "prof_id": (
- self.db.getProfId(self.box_person.currentText())
- if self.box_person.currentText() != ""
- else None
- ),
- "fach": (
- self.box_fach.currentText()
- if self.box_fach.currentText() != ""
- else None
- ),
- "erstellsemester": (
- self.box_erstellsemester.currentText()
- if self.box_erstellsemester.currentText() != ""
- else None
- ),
- "dauer": (
- "1"
- if self.box_dauerapp.currentText() == "Ja"
- else "0" if self.box_dauerapp.currentText() == "Nein" else None
- ),
- "endsemester": (
- self.box_semester.currentText()
- if self.box_semester.currentText() != ""
- else None
- ),
- "deletable": "True" if self.check_deletable.isChecked() else None,
- "deletesemester": self.generateSemester(today=True),
- }
- params = {
- key: value for key, value in params.items() if value is not None
- } # remove empty lines to prevent errors
- print(params)
- params = {
- key: value for key, value in params.items() if value != "Alle"
- } # remove empty lines to prevent errors
- print(params)
- result = self.db.statistic_request(**params)
- # add QTableWidgetItems to the table
- self.tableWidget.setRowCount(len(result))
- if len(result) == 0:
- self.db_err_message.setText("Keine Ergebnisse gefunden")
- return
- for i in range(len(result)):
- print(result[i])
- # set the items 0 = clickable checkbox, 1 = appname, 2 = profname, 3 = fach
- self.tableWidget.setItem(i, 0, QtWidgets.QTableWidgetItem(""))
- self.tableWidget.setItem(i, 1, QtWidgets.QTableWidgetItem(result[i][1]))
- self.tableWidget.setItem(
- i, 2, QtWidgets.QTableWidgetItem(str(result[i][4]))
- )
- self.tableWidget.setItem(i, 3, QtWidgets.QTableWidgetItem(result[i][2]))
- self.tableWidget.setItem(i, 4, QtWidgets.QTableWidgetItem(result[i][3]))
- # replace the 0 with a checkbox
- checkbox = QtWidgets.QCheckBox()
- checkbox.setChecked(False)
- self.tableWidget.setCellWidget(i, 0, checkbox)
- # if i[9] is 1, set the background of the row to red
- if int(result[i][9]) == 1:
- for j in range(5):
- self.tableWidget.item(i, j).setBackground(QtGui.QColor(235, 74, 71))
- # disable the checkbox
- self.tableWidget.cellWidget(i, 0).setEnabled(False)
- # set the tooltip
- self.tableWidget.cellWidget(i, 0).setToolTip(
- "Dieser Semesterapparat kann nicht gelöscht werden, da er bereits gelöscht wurde"
- )
-
- def populate_frame(self, appdata: ApparatData):
- # populate the frame with the data from the database
- # ic(appdata)
- self.drpdwn_app_nr.setCurrentText(str(appdata.appnr))
- self.prof_title.setText(appdata.prof_title)
- prof_name = appdata.profname.split(" ")
- if len(prof_name) > 2:
- fname = " ".join(prof_name[1:])
- lname = prof_name[0]
- prof_name = f"{lname}, {fname}"
- else:
- prof_name = ", ".join(prof_name)
- self.drpdwn_prof_name.setCurrentText(prof_name)
- self.prof_mail.setText(appdata.prof_mail)
- self.prof_tel_nr.setText(appdata.prof_tel)
- self.app_name.setText(appdata.appname)
- print("changing dropdown app_fach from '' to ", appdata.app_fach)
- self.app_fach.setCurrentText(appdata.app_fach)
- print("changed dropdown app_fach to ", self.app_fach.currentText())
- if appdata.semester is not None:
- self.sem_sommer.setChecked(
- True if appdata.semester.split(" ")[0] == "SoSe" else False
- )
- self.sem_winter.setChecked(
- True if appdata.semester.split(" ")[0] == "WiSe" else False
- )
- self.sem_year.setText(appdata.semester.split(" ")[1])
- else:
- self.sem_sommer.setChecked(
- True if appdata.erstellsemester.split(" ")[0] == "SoSe" else False
- )
- self.sem_winter.setChecked(
- True if appdata.erstellsemester.split(" ")[0] == "WiSe" else False
- )
- self.sem_year.setText(appdata.erstellsemester.split(" ")[1])
- self.check_eternal_app.setChecked(appdata.dauerapp)
- self.prof_id_adis.setText(str(appdata.prof_adis_id))
- self.apparat_id_adis.setText(str(appdata.apparat_adis_id))
- self.app_group_box.setEnabled(True)
- self.groupBox_2.hide()
- self.groupBox.hide()
- self.validateLoadedData()
-
- def validateLoadedData(self):
- self.validate_prof_mail()
- self.validate_prof_name()
- self.validate_prof_tel()
- self.validate_app_name()
- self.validate_app_fach()
- self.validate_semester()
-
- def update_apparat(self):
- appdata = ApparatData()
- appdata.app_fach = self.app_fach.currentText()
- appdata.appname = self.app_name.text()
- appdata.appnr = self.active_apparat
- appdata.dauerapp = self.check_eternal_app.isChecked()
- appdata.prof_mail = self.prof_mail.text()
- appdata.prof_tel = self.prof_tel_nr.text()
- appdata.prof_title = self.prof_title.text()
- appdata.profname = self.drpdwn_prof_name.currentText()
- appdata.semester = (
- self.sem_sommer.text() + " " + self.sem_year.text()
- if self.sem_sommer.isChecked()
- else self.sem_winter.text() + " " + self.sem_year.text()
- )
- appdata.prof_adis_id = self.prof_id_adis.text()
- self.add_files()
- appdata.apparat_adis_id = self.apparat_id_adis.text()
-
- self.db.updateApparat(appdata)
-
- self.update_app_media_list()
- self.cancel_active_selection.click()
- self.check_send_mail.show()
- self.chkbx_show_del_media.show()
- self.cancel_active_selection.setEnabled(False)
-
- def confirm_popup(self, message: str):
- popup = popus_confirm()
- popup.setupUi()
- popup.textEdit.setReadOnly(True)
- popup.textEdit.setText(message)
-
- popup.exec()
- return popup.result()
-
- def threads(self):
- while True:
- self.validate_prof_mail()
- self.validate_prof_name()
- self.validate_prof_tel()
- self.validate_app_name()
- self.validate_app_fach()
- self.validate_semester()
-
- def thread_check(self):
- 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)
- self.app_name.textChanged.connect(self.validate_app_name)
- self.app_fach.currentTextChanged.connect(self.validate_app_fach)
- self.sem_year.textChanged.connect(self.validate_semester)
- self.check_eternal_app.stateChanged.connect(self.validate_semester)
-
- def validate_prof_name(self):
- if self.app_group_box.isEnabled():
- if "," in self.drpdwn_prof_name.currentText():
- self.drpdwn_prof_name.setStyleSheet("border: 1px solid green;")
- self.profname_mand.setText("")
- self.change_state(0, 1)
- else:
- self.drpdwn_prof_name.setStyleSheet("border: 1px solid red;")
- self.profname_mand.setText("*")
- self.change_state(0, 0)
- else:
- pass
- # self.drpdwn_prof_name.setStyleSheet("border: 1px solid black;")
-
- def validate_prof_mail(self):
- if self.app_group_box.isEnabled():
- if self.prof_mail.hasAcceptableInput():
- self.prof_mail.setStyleSheet("border: 1px solid green;")
- self.mail_mand.setText("")
- self.change_state(1, 1)
- else:
- self.prof_mail.setStyleSheet("border: 1px solid red;")
- self.mail_mand.setText("*")
- self.change_state(1, 0)
- else:
- self.prof_mail.setStyleSheet("border: 1px solid black;")
-
- def validate_prof_tel(self):
- if self.app_group_box.isEnabled():
- if self.prof_tel_nr.text() != "":
- self.prof_tel_nr.setStyleSheet("border: 1px solid green;")
- self.telnr_mand.setText("")
- self.change_state(2, 1)
- else:
- self.prof_tel_nr.setStyleSheet("border: 1px solid red;")
- self.telnr_mand.setText("*")
- self.change_state(2, 0)
-
- def validate_app_name(self):
- if self.app_group_box.isEnabled():
- if self.app_name.hasAcceptableInput():
- self.app_name.setStyleSheet("border: 1px solid green;")
- self.appname_mand.setText("")
- self.change_state(3, 1)
- else:
- self.app_name.setStyleSheet("border: 1px solid red;")
- self.appname_mand.setText("*")
- self.change_state(3, 0)
-
- def validate_app_fach(self):
- if self.app_group_box.isEnabled():
- if self.app_fach.currentText() != "":
- self.app_fach.setStyleSheet("border: 1px solid green;")
- self.fach_mand.setText("")
- self.change_state(4, 1)
- else:
- self.app_fach.setStyleSheet("border: 1px solid red;")
- self.fach_mand.setText("*")
- self.change_state(4, 0)
-
- def validate_semester(self):
- if self.app_group_box.isEnabled():
- if (
- (self.sem_sommer.isChecked() or self.sem_winter.isChecked())
- and self.sem_year.hasAcceptableInput()
- ) or self.check_eternal_app.isChecked():
- self._mand.setText("")
- self.change_state(5, 1)
- self.check_eternal_app.setEnabled(True)
- else:
- self._mand.setText("*")
- self.change_state(5, 0)
- self.check_eternal_app.setEnabled(False)
-
- def change_state(self, index, state):
- global valid_input
- valid_input = list(valid_input)
- valid_input[index] = state
- valid_input = tuple(valid_input)
-
- def set_state(self):
- # set state of semester and year
- if self.check_eternal_app.isChecked():
- self.sem_winter.setEnabled(False)
- self.sem_sommer.setEnabled(False)
- self.sem_year.setEnabled(False)
- else:
- self.sem_winter.setEnabled(True)
- self.sem_sommer.setEnabled(True)
- self.sem_year.setEnabled(True)
-
- def validate_fields(self):
- return all(valid_input)
-
- # def req_fields_filled(self):
- # # check if all required fields are filled
- # values = []
- # for item in self.app_group_box.findChildren(QtWidgets.QLabel):
- # # if label name contains "req" and the text is empty, return false
- # if "mand" in item.objectName() and item.text() == "":
- # values.append(True)
- # elif "mand" in item.objectName() and item.text() != "":
- # values.append(False)
- # return all(values)
- #
- def buttonClicked(self):
- print("Button clicked")
-
- def set_prof_data(self):
- if "," not in self.drpdwn_prof_name.currentText():
- self.prof_mail.clear()
- self.prof_tel_nr.clear()
- return
- selected_prof = self.drpdwn_prof_name.currentText()
- data = self.db.getProfData(selected_prof)
- # ic(data)
- prof_title = data[2]
- if prof_title == "None":
- prof_title = "Kein Titel"
- self.prof_title.setText(prof_title)
- self.prof_tel_nr.setText(data[1])
- self.prof_mail.setText(data[0])
-
- def get_index_of_value(self, table_widget, value):
- for i in range(table_widget.rowCount()):
- for j in range(table_widget.columnCount()):
- if (
- table_widget.item(i, j) is not None
- and table_widget.item(i, j).text() == value
- ):
- return i, j
- return None
-
- def load_app_data(self, app_id=None):
- self.cancel_active_selection.setEnabled(True)
- if isinstance(app_id, str):
- # double click the tableWidget_apparate row with the given app_id
- row, column = self.get_index_of_value(self.tableWidget_apparate, app_id)
- # set the current index to the row
- self.tableWidget_apparate.setCurrentCell(row, 0)
- self.check_send_mail.hide()
- app_pos = self.tableWidget_apparate.currentIndex()
- appnr = self.tableWidget_apparate.item(app_pos.row(), 0).text()
- appname = self.tableWidget_apparate.item(app_pos.row(), 1).text()
- self.sem_sommer.setEnabled(False)
- self.sem_winter.setEnabled(False)
- self.sem_year.setEnabled(False)
- self.dokument_list.setRowCount(0)
- self.chkbx_show_del_media.setEnabled(True)
- appdata = self.db.getApparatData(appnr, appname)
- self.populate_frame(appdata)
- self.btn_apparat_save.hide()
- self.btn_reserve.show()
- self.chkbx_show_del_media.show()
- self.groupBox_2.show()
- self.groupBox.show()
-
- self.drpdwn_app_nr.setDisabled(True)
- self.update_app_media_list()
- self.update_documemt_list()
-
- def update_documemt_list(self):
- app_id = self.active_apparat
- prof_id = self.db.getProfId(
- self.drpdwn_prof_name.currentText().replace(", ", " ")
- )
- files = self.db.getFiles(app_id, prof_id)
- for file in files:
- self.dokument_list.insertRow(0)
- self.dokument_list.setItem(0, 0, QtWidgets.QTableWidgetItem(file[0]))
- self.dokument_list.setItem(0, 1, QtWidgets.QTableWidgetItem(file[1]))
- self.dokument_list.setItem(0, 2, QtWidgets.QTableWidgetItem(""))
- self.dokument_list.setItem(0, 3, QtWidgets.QTableWidgetItem("Database"))
-
- # def btn_load_apparat(self):
- # # remove all rows from table
- # #get all
- # self.tableWidget_apparate.sortItems(0, QtCore.Qt.SortOrder.AscendingOrder)
- # self.app_group_box.setDisabled(True)
- # for child in self.app_group_box.findChildren(QtWidgets.QLineEdit):
- # child.clear()
-
- def btn_create_new_apparat(self):
- self.groupBox.show()
- self.groupBox_2.show()
- global valid_input
- # *create a new apparat
- self.btn_apparat_save.show() if self.btn_apparat_save.isHidden() else None
- # clear dokumemt_list
- self.dokument_list.setRowCount(0)
- self.cancel_active_selection.setEnabled(True)
- self.app_group_box.setEnabled(True)
-
- self.sem_year.setEnabled(True)
- self.sem_sommer.setEnabled(True)
- self.sem_winter.setEnabled(True)
- self.chkbx_show_del_media.setEnabled(True)
- self.drpdwn_app_nr.setEnabled(True)
- self.app_fach.setEnabled(True)
-
- if self.tableWidget_apparat_media.rowCount() > 0:
- self.tableWidget_apparat_media.setRowCount(0)
- # clear all fields
- for item in self.app_group_box.findChildren(QtWidgets.QLineEdit):
- item.clear()
- self.drpdwn_app_nr.clear()
- self.prof_title.clear()
- self.drpdwn_prof_name.clear()
- # set drop down menu for apparat numbers to only available numbers
- self.drpdwn_app_nr.addItems(
- [str(i) for i in APP_NRS if i not in self.db.getUnavailableApparatNumbers()]
- )
-
- valid_input = (0, 0, 0, 0, 0, 0)
- self.populate_prof_dropdown()
- # self.horizontalLayout_6.show()
- # increase size by 300px
-
- def update_progress_label(self, curr, total):
- text = f"Medium {curr}/{total}"
- self.logger.log_info(text)
- self.progress_label.setText(text)
- # update tableWidget_apparat_media
- self.update_app_media_list()
-
- def hide_progress_label(self):
- self.logger.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):
- if not self.app_group_box.isEnabled():
- self.confirm_popup("Bitte erst einen Apparat auswählen!")
- return
-
- def __new_ui():
- dialog = QtWidgets.QDialog()
- frame = Medien()
- frame.setupUi(dialog)
- dialog.exec()
- mode = frame.get_mode()
- data = frame.get_list_data()
- return mode, data, dialog.result()
-
- self.progress_label.show()
- self.line_2.show()
- self.label_info.show()
- self.progress_label.setText("Bitte warten...")
- mode, data, result = __new_ui()
- if result == 1:
- if data == []:
- self.confirm_popup("Bitte mindestens ein Medium hinzufügen!")
-
- app_id = self.active_apparat
- prof_id = self.db.getProfId(self.drpdwn_prof_name.currentText())
- # check if app_id is in database
- if not self.db.checkApparatExists(app_id):
- # create apparat
- self.btn_save_apparat()
- # create a thread that updates the progress label after each medium
- self.bookGrabber = BookGrabber(
- mode=mode, app_id=app_id, prof_id=prof_id, data=data
- )
- # grabber.mode = mode
- # grabber.data = data
- # grabber.app_id = app_id
- # grabber.prof_id = prof_id
- self.bookGrabber.finished.connect(self.bookGrabber.deleteLater)
- self.bookGrabber.finished.connect(self.hide_progress_label)
- self.bookGrabber.finished.connect(self.update_app_media_list)
- self.bookGrabber.updateSignal.connect(self.update_progress_label)
-
- self.bookGrabber.start()
- # run grabber.deletelater
-
- # for book in data:
- # # self.progress_label.setText(f"Medium {ct}/{len(data)}")
- # # update the progress label
- # self.logger.log_info(f"trying to add BookData for Signature {book}")
- # webdata = WebRequest().get_ppn(book).get_data()
- # bd: BookData = BibTextTransformer(mode).get_data(webdata).return_data()
- # bd.signature = book
- # self.db.addBookToDatabase(bookdata=bd, app_id=app_id, prof_id=prof_id)
-
- # get all media list books
-
- else:
- return
-
- def check_availability(self):
- # self.threadeds.clear()
-
- def _update_progress(current, all_titles):
- self.avail_status.setText("{}/{}".format(current, all_titles))
-
- def _hide_progress_label():
- self.label_20.hide()
- self.avail_status.hide()
- self.avail_status.setText("0/0")
-
- # get all links from the table
- # if no index in tableWidget_apparat_media is selected, check all
- if self.tableWidget_apparat_media.currentRow() == -1:
- links = [
- self.tableWidget_apparat_media.item(i, 1).text()
- for i in range(self.tableWidget_apparat_media.rowCount())
- if self.tableWidget_apparat_media.item(i, 4).text() == "❌"
- or self.tableWidget_apparat_media.item(i, 4).text() == ""
- ]
- else:
- links = [
- self.tableWidget_apparat_media.item(
- self.tableWidget_apparat_media.currentRow(), 1
- ).text()
- ]
- items = len(links)
- self.label_20.setText("Verfügbarkeit wird geprüft, bitte warten...")
- self.label_20.show()
- self.avail_status.setText(f"0/{items}")
- self.avail_status.show()
- books = self.db.getBooks(
- self.active_apparat,
- self.db.getProfId(self.drpdwn_prof_name.currentText()),
- deleted=0,
- )
-
- # thread = QThread()
- appnumber = self.active_apparat
- print(links)
- self.availChecker = AvailChecker(links, appnumber, books=books)
- # availcheck.moveToThread(thread)
- # availcheck.finished.connect(thread.quit)
- self.availChecker.finished.connect(self.availChecker.deleteLater)
- self.availChecker.finished.connect(self.update_app_media_list)
- self.availChecker.updateProgress.connect(_update_progress)
- self.availChecker.finished.connect(_hide_progress_label)
- self.availChecker.start()
- # kill availcheck after completion
-
- # self.threadeds.append(thread)
- # self.grabbers.append(availcheck)
-
- def btn_cancel_active_selection(self):
- # clear the rows of the table
- self.tableWidget_apparat_media.setRowCount(0)
- self.dokument_list.setRowCount(0)
- self.app_group_box.setEnabled(False)
- self.app_fach.setCurrentText("")
- self.chkbx_show_del_media.hide()
- self.check_send_mail.hide()
- self.btn_reserve.hide()
- self.groupBox_2.hide()
- self.groupBox.hide()
- self.check_eternal_app.setEnabled(False)
- # set all radio buttons to unchecked
- self.sem_sommer.setChecked(False)
- self.sem_winter.setChecked(False)
-
- for child in self.app_group_box.findChildren(QtWidgets.QLineEdit):
- child.clear()
-
- def update_app_media_list(self):
- deleted = 0 if not self.chkbx_show_del_media.isChecked() else 1
- app_id = self.active_apparat
- prof_id = self.db.getProfId(self.drpdwn_prof_name.currentText())
- books: list[dict[int, BookData, int]] = self.db.getBooks(
- app_id, prof_id, deleted
- )
-
- # print(books)
- # take the dataclass from the tuple
- # booklist:list[BookData]=[book[0] for book in books]
- self.tableWidget_apparat_media.setRowCount(0)
- for book in books:
- book["id"]
- book_data = book["bookdata"]
- availability = book["available"]
- # bd = BookData().from_string(book)
- # print(bd, type(bd))
- # create a new row below the last one
- self.tableWidget_apparat_media.insertRow(
- self.tableWidget_apparat_media.rowCount()
- )
- # #set the data
- self.tableWidget_apparat_media.setItem(
- self.tableWidget_apparat_media.rowCount() - 1,
- 0,
- QtWidgets.QTableWidgetItem(book_data.title),
- )
- self.tableWidget_apparat_media.setItem(
- self.tableWidget_apparat_media.rowCount() - 1,
- 1,
- QtWidgets.QTableWidgetItem(book_data.signature),
- )
- self.tableWidget_apparat_media.setItem(
- self.tableWidget_apparat_media.rowCount() - 1,
- 2,
- QtWidgets.QTableWidgetItem(book_data.edition),
- )
- self.tableWidget_apparat_media.setItem(
- self.tableWidget_apparat_media.rowCount() - 1,
- 3,
- QtWidgets.QTableWidgetItem(book_data.author),
- )
- self.tableWidget_apparat_media.setItem(
- self.tableWidget_apparat_media.rowCount() - 1,
- 6,
- QtWidgets.QTableWidgetItem(book_data.link),
- )
- if availability == 1:
- # display green checkmark at column 4 in the row
- self.tableWidget_apparat_media.setItem(
- self.tableWidget_apparat_media.rowCount() - 1,
- 4,
- QtWidgets.QTableWidgetItem("✅"),
- )
- # set tooltip
- self.tableWidget_apparat_media.item(
- self.tableWidget_apparat_media.rowCount() - 1, 4
- ).setToolTip("Das Medium wurde im Apparat gefunden")
- else:
- self.tableWidget_apparat_media.setItem(
- self.tableWidget_apparat_media.rowCount() - 1,
- 4,
- QtWidgets.QTableWidgetItem("❌"),
- )
- self.tableWidget_apparat_media.item(
- self.tableWidget_apparat_media.rowCount() - 1, 4
- ).setToolTip("Das Medium wurde nicht im Apparat gefunden")
-
- # make table link clickable
- self.tableWidget_apparat_media.itemClicked.connect(self.open_link)
-
- def open_link(self, item):
- def __openLink(link):
- if link == "":
- return
- if "http" not in link:
- link = "https://" + link
-
- webbrowser.open(link)
-
- # get the name of the column
- columnname = self.tableWidget_apparat_media.horizontalHeaderItem(
- item.column()
- ).text()
- if columnname == "Link":
- __openLink(item.text())
- else:
- pass
-
- def text_to_clipboard(self):
- app_id = self.active_apparat
- text = f"SQ=select distinct akkey from aupr01 where aufst='{app_id}' union select pr_isn from aks4pd where akruf ='{app_id}'"
- clipboard = QtWidgets.QApplication.clipboard()
- clipboard.setText(text)
-
- def populate_prof_dropdown(self):
- profs = self.db.getProfs()
- # add empty entry to dropdown and set it as current
- self.drpdwn_prof_name.addItem("Kein Name")
- for prof in profs:
- self.drpdwn_prof_name.addItem(f"{prof[3]}, {prof[2]}")
-
- def add_document(self):
- print("Add document")
- picker = FilePicker()
- files = picker.pick_files()
-
- for file in files:
- print(file)
- filename = file.split("/")[-1]
- filetype = filename.split(".")[-1]
- self.dokument_list.insertRow(0)
- self.dokument_list.setItem(0, 0, QtWidgets.QTableWidgetItem(filename))
- self.dokument_list.setItem(0, 1, QtWidgets.QTableWidgetItem(filetype))
- self.dokument_list.setItem(0, 2, QtWidgets.QTableWidgetItem("*"))
- self.dokument_list.setItem(0, 3, QtWidgets.QTableWidgetItem(file))
- # set tooltip of row 3 to the file path for each row
- self.dokument_list.item(0, 3).setToolTip(file)
-
- # self.db.insert_file(files, self.active_apparat, self.db.get_prof_id(self.drpdwn_prof_name.currentText()))
-
- def open_document(self):
- _selected_doc_name = ""
- _selected_doc_filetype = ""
- try:
- _selected_doc_name = self.dokument_list.item(
- self.dokument_list.currentRow(), 0
- ).text()
- _selected_doc_location = self.dokument_list.item(
- self.dokument_list.currentRow(), 3
- ).text()
- _selected_doc_filetype = self.dokument_list.item(
- self.dokument_list.currentRow(), 1
- ).text()
- except AttributeError:
- self.confirm_popup("Bitte erst ein Dokument auswählen!")
- return
- if not _selected_doc_location == "Database":
- path = Path(_selected_doc_location)
- path: Path = path + "/" + _selected_doc_name
- if os.getenv("OS") == "Windows_NT":
- path = path.resolve()
- os.startfile(path)
- else:
- path = path.resolve()
- os.system(f"open {path}")
- else:
- recreateFile(
- _selected_doc_name, self.active_apparat, filetype=_selected_doc_filetype
- )
- # # if ~ in path, replace it with the home directory
- # if "~" in path:
- # path = path.replace("~", str(Path.home()))
- # path = Path(path)
-
- def add_media_from_file(self):
- def __open_dialog(signatures):
- dialog = QtWidgets.QDialog()
- frame = parsed_titles_ui()
- frame.setupUi(dialog)
- dialog.show()
- frame.signatures = signatures
- frame.populate_table()
- frame.progressBar.setMaximum(len(signatures))
- frame.progressBar.setValue(0)
- frame.progressBar.show()
- frame.count.setText(str(len(signatures)))
- frame.toolButton.click()
- data = frame.return_data()
- print(data)
- # if no data was returned, return
-
- return data
- # get
-
- # if files are in the table, and are selected, check for books in the file
- if self.dokument_list.rowCount() == 0:
- return
- else:
- # if file is selected, check for books in the file
- if self.dokument_list.currentRow() != -1:
- print("File selected")
- file = self.dokument_list.item(
- self.dokument_list.currentRow(), 3
- ).text()
-
- file_type = self.dokument_list.item(
- self.dokument_list.currentRow(), 1
- ).text()
- file_location = self.dokument_list.item(
- self.dokument_list.currentRow(), 3
- ).text()
- file_name = self.dokument_list.item(
- self.dokument_list.currentRow(), 0
- ).text()
- if file_location == "Database":
- # create a temporaty file to use, delete it after use
- temp_file = tempfile.NamedTemporaryFile(
- delete=False, suffix="." + file_type
- )
- temp_file.write(
- self.db.getBlob(file_name, int(self.active_apparat))
- )
- temp_file.close()
- file = temp_file.name
- print(file)
- if file_type == "pdf":
- # Todo: implement parser here
- self.confirm_popup("PDF Dateien werden nochnicht unterstützt!")
- return
- if file_type == "csv":
- signatures = csv_to_list(file)
- data = __open_dialog(signatures)
- # get the app_id and prof_id
- app_id = self.active_apparat
- prof_id = self.db.getProfId(self.drpdwn_prof_name.currentText())
- # add the data to the database
- for book in data:
- if type(book) != BookData:
- continue
- self.db.addBookToDatabase(
- bookdata=book, app_id=app_id, prof_id=prof_id
- )
- if file_type == "docx":
- data = word_docx_to_csv(file)
- signatures = [
- i
- for i in data["Standnummer"].values
- if i != "\u2002\u2002\u2002\u2002\u2002"
- ]
- data = __open_dialog(signatures)
- # if no data was returned, return
- if data == []:
- return
- # get the app_id and prof_id
- app_id = self.active_apparat
- prof_id = self.db.getProfId(self.drpdwn_prof_name.currentText())
- # add the data to the database
- for book in data:
- if type(book) != BookData:
- continue
- self.db.addBookToDatabase(
- bookdata=book, app_id=app_id, prof_id=prof_id
- )
- self.update_app_media_list()
- print(len(signatures))
-
- def btn_check_file_threaded(self):
- print("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
- prof_id = self.db.getProfId(self.drpdwn_prof_name.currentText())
- # check if apparat in database
-
- # if app_id not in database, create apparat
- if not self.db.checkApparatExistsById(app_id):
- # create apparat
- print("Creating apparat")
- self.btn_save_apparat()
- if self.dokument_list.rowCount() == 0:
- print("No file selected")
- self.tableWidget_apparate.setEnabled(True)
- self.tableWidget_apparate.setToolTip("")
- return
- else:
- # if file is selected, check for books in the file
- print("File selected")
- file = self.dokument_list.item(self.dokument_list.currentRow(), 3).text()
-
- file_type = self.dokument_list.item(
- self.dokument_list.currentRow(), 1
- ).text()
- file_location = self.dokument_list.item(
- self.dokument_list.currentRow(), 3
- ).text()
- file_name = self.dokument_list.item(
- self.dokument_list.currentRow(), 0
- ).text()
- if file_location == "Database":
- file = recreateFile(file_name, app_id, file_type, open=False)
- else:
- self.add_files()
- if file_type == "pdf":
- # Todo: implement parser here
- self.confirm_popup("PDF Dateien werden noch nicht unterstützt!")
- return
- if file_type == "csv":
- signatures = csv_to_list(file)
- # add the data to the database
- if file_type == "docx":
- data = word_docx_to_csv(file)
- signatures = [
- i
- for i in data["Standnummer"].values
- if i != "\u2002\u2002\u2002\u2002\u2002"
- ]
-
- signatures = [i for i in signatures if i != ""]
- # ic(signatures)
- print("starting thread")
- self.autoGrabber = BookGrabber(
- mode="ARRAY", app_id=app_id, prof_id=prof_id, data=signatures
- )
- # grabber.mode = "ARRAY"
- # grabber.data = signatures
- # grabber.app_id = app_id
- # grabber.prof_id = prof_id
- # grabber.moveToThread(thread)
- self.label_info.show()
- self.progress_label.show()
- self.line_2.show()
- # grabber.finished.connect(thread.quit)
- self.autoGrabber.finished.connect(self.autoGrabber.deleteLater)
- self.autoGrabber.finished.connect(self.hide_progress_label)
- self.autoGrabber.finished.connect(self.update_app_media_list)
- self.autoGrabber.finished.connect(self.unlock_apparate)
- self.autoGrabber.updateSignal.connect(self.update_progress_label)
- # worker.finished.connect(worker.deleteLater)
-
- self.autoGrabber.start()
- # self.thread = thread
- # kill grabber after completion
- # self.grabbers.append(grabber)
-
- def unlock_apparate(self):
- self.tableWidget_apparate.setEnabled(True)
- self.tableWidget_apparate.setToolTip("")
-
- def btn_save_apparat(self):
- def __clear_fields():
- self.drpdwn_app_nr.clear()
- self.prof_title.clear()
- self.drpdwn_prof_name.clearMask()
- self.app_name.clear()
- self.prof_mail.clear()
- self.prof_tel_nr.clear()
- self.app_fach.setCurrentText("")
- self.app_name.clear()
- self.sem_year.clear()
- self.dokument_list.setRowCount(0)
- self.sem_winter.setChecked(False)
- self.sem_sommer.setChecked(False)
- self.check_eternal_app.setChecked(False)
- self.prof_id_adis.clear()
- self.prof_id_adis.clear()
- self.apparat_id_adis.clear()
- self.drpdwn_prof_name.clear()
- self.tableWidget_apparat_media.setRowCount(0)
- self.app_group_box.setEnabled(False)
- self.groupBox_2.hide()
- self.groupBox.hide()
- self.check_send_mail.setChecked(False)
- self.cancel_active_selection.setEnabled(False)
-
- if not self.validate_fields():
- self.confirm_popup("Bitte alle Pflichtfelder ausfüllen!")
- return
- appd = ApparatData()
- appd.appnr = self.active_apparat
- appd.prof_title = (
- None if self.prof_title.text() == "" else self.prof_title.text()
- )
- appd.profname = self.drpdwn_prof_name.currentText()
- appd.appname = self.app_name.text()
- appd.semester = self.generateSemester()
- appd.dauerapp = 1 if self.check_eternal_app.isChecked() else 0
- appd.prof_tel = self.prof_tel_nr.text()
- appd.prof_mail = self.prof_mail.text()
- appd.app_fach = self.app_fach.currentText()
- appd.erstellsemester = self.generateSemester()
- appd.deleted = 0
- appd.prof_adis_id = self.prof_id_adis.text()
- appd.apparat_adis_id = self.apparat_id_adis.text()
- if self.dokument_list.rowCount() > 0:
- self.add_files()
- if not self.validate_fields():
- pass
- self.db.createApparat(appd)
- # if self.dokument_list.rowCount() > 0:
- self.add_files()
- appdata = self.db.getAllAparats()
- # merge self.appdata and appdata, remove duplicates
- self.apparats = list(set(self.apparats + appdata))
- self.apparats = natsorted(self.apparats, key=lambda x: x[4], reverse=True)
- self.update_apparat_list()
-
- # self.btn_load_apparat()
-
- if self.check_send_mail.isChecked():
- self.contact_prof(
- apparat=appd.appnr, mail="Information zum Semesterapparat"
- )
- __clear_fields()
-
- def send_mail_preview(self):
- pass
-
- @property
- def active_apparat(self):
- return self.drpdwn_app_nr.currentText()
-
- def add_files(self):
- files = []
- for i in range(self.dokument_list.rowCount()):
- files.append(
- {
- "name": self.dokument_list.item(i, 0).text(),
- "type": self.dokument_list.item(i, 1).text(),
- "date": self.dokument_list.item(i, 2).text(),
- "path": self.dokument_list.item(i, 3).text(),
- }
- )
- self.dokument_list.item(i, 2).setText("")
- self.db.insertFile(
- files,
- self.active_apparat,
- self.db.getProfId(self.drpdwn_prof_name.currentText()),
- )
-
- def update_apparat_list(self):
- # get a list of new apparats based on self.apparats and self.old_apparats
- new_apparats = [
- apparat for apparat in self.apparats if apparat not in self.old_apparats
- ]
- print(new_apparats)
- # insert the new apparats into the table
- for apparat in new_apparats:
- self.insert_apparat_into_table(apparat)
- # sort the table by apparat number using natural sorting
- self.tableWidget_apparate.sortItems(0, QtCore.Qt.SortOrder.AscendingOrder)
- self.old_apparats = self.apparats
-
- def insert_apparat_into_table(self, apparat):
- # ic(apparat)
- def __dauer_check(apparat):
- return "Ja" if apparat[7] == 1 else "Nein"
-
- self.tableWidget_apparate.insertRow(0)
- self.tableWidget_apparate.setItem(
- 0, 0, QtWidgets.QTableWidgetItem(str(apparat[4]))
- )
- self.tableWidget_apparate.setItem(
- 0, 1, QtWidgets.QTableWidgetItem(str(apparat[1]))
- )
- self.tableWidget_apparate.setItem(
- 0,
- 2,
- QtWidgets.QTableWidgetItem(
- self.db.getProfNameById(apparat[2], add_title=False)
- ),
- )
- self.tableWidget_apparate.setItem(
- 0,
- 3,
- QtWidgets.QTableWidgetItem(
- str(apparat[8]) if apparat[8] is not None else apparat[5]
- ),
- )
- self.tableWidget_apparate.setItem(
- 0, 4, QtWidgets.QTableWidgetItem(__dauer_check(apparat))
- )
- self.tableWidget_apparate.setItem(
- 0, 5, QtWidgets.QTableWidgetItem(str(apparat[13]))
- )
- self.logger.log_info(f"Inserted apparat {apparat[4]}")
-
- def open_context_menu(self, position):
- menu = QtWidgets.QMenu()
- extend_action = menu.addAction("Verlängern")
- contact_action = menu.addAction("Kontaktieren")
- delete_action = menu.addAction("Löschen")
- remind_action = menu.addAction("Erinnerung")
- menu.addAction(extend_action)
- menu.addActions([contact_action, delete_action, remind_action])
- extend_action.triggered.connect(self.extend_apparat)
- delete_action.triggered.connect(self.delete_apparat)
- contact_action.triggered.connect(self.contact_prof)
- remind_action.triggered.connect(self.reminder)
- menu.exec(self.tableWidget_apparate.mapToGlobal(position))
-
- def statistics_table_context_menu(self, position):
- menu = QtWidgets.QMenu()
- restore_action = menu.addAction("Wiederherstellen")
- menu.addAction(restore_action)
- restore_action.triggered.connect(self.restore_apparat)
- menu.exec(self.tableWidget.mapToGlobal(position))
-
- def restore_apparat(self):
- row = self.tableWidget.currentRow()
- apparat = self.tableWidget.item(row, 1).text()
- ic(apparat)
- apparat_id = self.db.getApparatId(apparat)
- # restore the apparat
- self.db.restoreApparat(apparat_id)
- # update the table
- self.reload()
-
- def reminder(self):
- self.logger.log_info("Opening reminder dialog")
- dialog = QtWidgets.QDialog()
- reminder = reminder_ui()
- reminder.setupUi(dialog)
- dialog.exec()
- if dialog.result() == QtWidgets.QDialog.DialogCode.Accepted:
- data = reminder.return_message()
- print(data)
- self.db.addMessage(
- data,
- self.active_user,
- self.active_apparat if self.active_apparat != "" else None,
- )
- self.calendarWidget.setMessages([data])
- self.calendarWidget.updateCells()
- # self.db.update_bookdata(data, book_id)
- # self.db.update_bookdata(data)
- self.logger.log_info("Commited message to database")
- # self.update_app_media_list()
-
- def get_reminders(self):
- messages = self.db.getMessages()
- self.logger.log_info(f"Got {len(messages)} messages from database")
- self.calendarWidget.setMessages(messages)
- self.calendarWidget.updateCells()
-
- def open_reminder(self):
- def __update_message():
- message_select = self.spin_select_message.value()
- try:
- message = messages[message_select - 1]
- except IndexError:
- self.message_frame.hide()
- return
- self.message_box.setText(message["message"])
- appnr = message["appnr"]
- appnr = "/" if appnr is None else str(appnr)
- self.line_app_info.setText(appnr)
-
- def __delete_message():
- message = messages[self.spin_select_message.value() - 1]
- self.db.deleteMessage(message["id"])
- # remove message from list
- messages.remove(message)
- self.spin_select_message.setMaximum(len(messages))
- self.spin_select_message.setValue(1)
- self.label_total_day_messages.setText("/ " + str(len(messages)))
- #
-
- selected_date = self.calendarWidget.selectedDate().toString("yyyy-MM-dd")
- print(selected_date)
- messages = self.db.getMessages(selected_date)
- if messages == []:
- self.message_frame.hide() if self.message_frame.isVisible() else None
- return
- print(messages)
- message_count = len(messages)
- self.spin_select_message.setMaximum(message_count)
- self.message_frame.show()
- self.label_total_day_messages.setText("/ " + str(message_count))
- # if there is only one message, disable the spinbox
- (
- self.spin_select_message.setEnabled(False)
- if message_count == 1
- else self.spin_select_message.setEnabled(True)
- )
- self.spin_select_message.setValue(1)
- # load the first message
- __update_message()
- # on valuechanged, update the message
- self.spin_select_message.valueChanged.connect(__update_message)
- self.btn_delete_message.clicked.connect(__delete_message)
-
- def open_settings(self):
- settings = settings_ui(self.active_user)
- settings.exec()
- if settings.result() == QtWidgets.QDialog.DialogCode.Accepted:
- data = settings.return_data()
- print(data)
- OmegaConf.save(data, "config.yaml")
- # re-load the config
- OmegaConf.load("config.yaml")
- self.logger.log_info("Saved settings to config.yaml")
- self.reload()
-
- def reload(self):
- # create a new connection to the database, refresh table data and replace the old connection
- self.db = Database()
- self.apparats = self.db.getAllAparats(deleted=0)
- self.apparats = natsorted(self.apparats, key=lambda x: x[4], reverse=True)
- self.tableWidget_apparate.setRowCount(0)
- for apparat in self.apparats:
- self.insert_apparat_into_table(apparat)
-
- def media_context_menu(self, position):
- menu = QtWidgets.QMenu()
- delete_action = menu.addAction("Löschen")
- edit_action = menu.addAction("Bearbeiten")
- menu.addAction(delete_action)
- menu.addAction(edit_action)
- delete_action.triggered.connect(self.delete_medium)
- edit_action.triggered.connect(self.edit_medium)
- menu.exec(self.tableWidget_apparat_media.mapToGlobal(position))
-
- def edit_medium(self):
- book = self.tableWidget_apparat_media.item(
- self.tableWidget_apparat_media.currentRow(), 1
- ).text()
- data = self.db.getBookBasedOnSignature(
- app_id=self.active_apparat,
- signature=book,
- prof_id=self.db.getProfId(self.drpdwn_prof_name.currentText()),
- )
- book_id = self.db.getBookIdBasedOnSignature(
- self.active_apparat,
- self.db.getProfId(self.drpdwn_prof_name.currentText()),
- book,
- )
- widget = QtWidgets.QDialog()
- bookedit = edit_bookdata_ui()
- bookedit.setupUi(widget)
- # change title of dialog
- widget.setWindowTitle("Metadaten")
- bookedit.populate_fields(data)
- widget.exec()
- if widget.result() == QtWidgets.QDialog.DialogCode.Accepted:
- data = bookedit.get_data()
- print(data)
- self.db.updateBookdata(data, book_id)
- # self.db.update_bookdata(data)
- print("accepted")
- self.update_app_media_list()
- else:
- return
- pass
-
- def delete_medium(self):
- selected_apparat_id = self.tableWidget_apparate.item(
- self.tableWidget_apparate.currentRow(), 0
- ).text()
- # check how many rows are selected
- selected_rows = self.tableWidget_apparat_media.selectionModel().selectedRows()
- if len(selected_rows) == 1:
- signature = self.tableWidget_apparat_media.item(
- self.tableWidget_apparat_media.currentRow(), 1
- ).text()
- book_id = self.db.getBookIdBasedOnSignature(
- selected_apparat_id,
- prof_id=self.db.getProfId(self.drpdwn_prof_name.currentText()),
- signature=signature,
- )
- 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)
- print(state)
- if state == 1:
- self.db.deleteBook(book_id)
- self.update_app_media_list()
- self.contact_prof(mail="deleted")
- pass
- else:
- # get all selected rows
- ranges = self.tableWidget_apparat_media.selectedRanges()
- rows = []
- for r in ranges:
- for row in range(r.topRow(), r.bottomRow() + 1):
- rows.append(row)
- print(rows)
- message = f"Sollen die {len(rows)} Medien wirklich gelöscht werden?"
- state = self.confirm_popup(message)
- if state == 1:
- for _ in rows:
- signature = self.tableWidget_apparat_media.item(_, 1).text()
- book_id = self.db.getBookIdBasedOnSignature(
- selected_apparat_id,
- prof_id=self.db.getProfId(self.drpdwn_prof_name.currentText()),
- signature=signature,
- )
- self.db.deleteBook(book_id)
- self.update_app_media_list()
-
- def extend_apparat(self):
- framework = QtWidgets.QDialog()
- frame = App_Ext_Dialog()
- frame.setupUi(framework)
- frame.sem_year.setText(str(QtCore.QDate.currentDate().year()))
- framework.exec()
- # return data from dialog if ok is pressed
- if framework.result() == QtWidgets.QDialog.DialogCode.Accepted:
- data = frame.get_data()
- print(data)
- # return data
- selected_apparat_id = self.tableWidget_apparate.item(
- self.tableWidget_apparate.currentRow(), 0
- ).text()
- print(selected_apparat_id)
- # update self.apparats with the new data
- # find matching apparat
- # for apparat in self.apparats:
- # if apparat[4] == int(selected_apparat_id):
- # apparat[5]=data["semester"]
- # apparat[7]=data["dauerapp"]
- # break
- # self.old_apparats = self.apparats
- self.db.setNewSemesterDate(
- selected_apparat_id, data["semester"], dauerapp=data["dauerapp"]
- )
- else:
- return
-
- def contact_prof(self, apparat=None, mail=""):
- print(apparat)
- if self.active_apparat == "":
- if apparat is False:
- self.confirm_popup("Bitte erst einen Apparat auswählen!")
- return
- else:
- # TODO: stuff
- pass
- else:
- if apparat:
- active_apparat_id = apparat
- else:
- active_apparat_id = self.drpdwn_app_nr.currentText()
- print(active_apparat_id)
- profname = self.drpdwn_prof_name.currentText().replace(",", "").split(" ")
- profname = f"{profname[1]} {profname[0]}"
- prof_id = self.db.getProfId(self.drpdwn_prof_name.currentText())
- pmail = self.db.getSpecificProfData(prof_id, ["mail"])
- # create a new thread to show the mail interface and send the mail
- self.mail_thread = Mail_Dialog(
- app_id=active_apparat_id,
- prof_name=profname,
- prof_mail=pmail,
- app_name=self.app_name.text(),
- app_subject=self.app_fach.currentText(),
- )
- self.mail_thread.show()
-
- def delete_apparat(self):
- selected_apparat_id = self.tableWidget_apparate.item(
- self.tableWidget_apparate.currentRow(), 0
- ).text()
- message = f"Soll der Apparat {selected_apparat_id} wirklich gelöscht werden?"
- state = self.confirm_popup(message)
- print(state)
- if state == 1:
- self.db.deleteApparat(selected_apparat_id, generateSemesterByDate())
- # delete the corresponding entry from self.apparats
- for apparat in self.apparats:
- if apparat[4] == int(selected_apparat_id):
- self.apparats.remove(apparat)
- break
- self.old_apparats = self.apparats
- print(self.apparats)
- # remove the row from the table
- self.tableWidget_apparate.removeRow(self.tableWidget_apparate.currentRow())
- # send mail to prof
- self.contact_prof(mail="deleted", apparat=selected_apparat_id)
- # if state==QtWidgets.QDialog.DialogCode.Accepted:
- # self.db.delete_apparat(selected_apparat_id)
- # pass
-
-
-def launch_gui():
- print("trying to login")
- print("checking if database available")
- # database = config.database.path + config.database.name
- # print(database)
- # if not os.path.exists(database):
- # print("Database not found, creating new database")
- # db = Database()
- # db.create_database()
- app = QtWidgets.QApplication(sys.argv)
- login_dialog = QtWidgets.QDialog()
- ui = login_ui()
- 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
- print(ui.lusername)
- MainWindow = QtWidgets.QMainWindow()
- aui = Ui(MainWindow, username=ui.lusername)
-
- print(aui.active_user)
- MainWindow.show()
- # atexit.register()
- atexit.register(delete_temp_contents)
- atexit.register(aui.validate_thread.quit)
- sys.exit(app.exec())
-
- elif ui.lresult == 0:
- warning_dialog = QtWidgets.QMessageBox()
- warning_dialog.setIcon(QtWidgets.QMessageBox.Icon.Warning)
- warning_dialog.setText("Invalid username or password. Please try again.")
- warning_dialog.setWindowTitle("Login Failed")
- warning_dialog.exec()
- elif ui.lresult == 2:
- # TODO: implement admin functionality here
- """change passwords for apparats, change passwords for users, list users, create and delete users etc"""
- # open a console window
- # console = ""
- print("admin")
- atexit.register(delete_temp_contents)
-
-
-if __name__ == "__main__":
- print("This is the main window")
- # app = QtWidgets.QApplication(sys.argv)
- # window = MainWindow()
- # app.exec()
- # open login screen
- launch_gui()
diff --git a/src/ui/Ui_plotdata.py b/src/ui/Ui_plotdata.py
deleted file mode 100644
index e0ee261..0000000
--- a/src/ui/Ui_plotdata.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\plotdata.ui'
-#
-# Created by: PyQt6 UI code generator 6.3.1
-#
-# 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.
-
-
-from PyQt6 import QtCore, QtWidgets
-
-
-class Ui_MainWindow(object):
- def setupUi(self, MainWindow):
- MainWindow.setObjectName("MainWindow")
- MainWindow.resize(640, 480)
- self.centralwidget = QtWidgets.QWidget(MainWindow)
- self.centralwidget.setObjectName("centralwidget")
- self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
- self.graphicsView.setGeometry(QtCore.QRect(330, 10, 256, 192))
- self.graphicsView.setObjectName("graphicsView")
- self.widget = QtWidgets.QWidget(self.centralwidget)
- self.widget.setGeometry(QtCore.QRect(10, 0, 251, 271))
- self.widget.setObjectName("widget")
- self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
- self.stackedWidget.setGeometry(QtCore.QRect(300, 220, 291, 201))
- self.stackedWidget.setObjectName("stackedWidget")
- self.page = QtWidgets.QWidget()
- self.page.setObjectName("page")
- self.stackedWidget.addWidget(self.page)
- self.page_2 = QtWidgets.QWidget()
- self.page_2.setObjectName("page_2")
- self.stackedWidget.addWidget(self.page_2)
- MainWindow.setCentralWidget(self.centralwidget)
- self.menubar = QtWidgets.QMenuBar(MainWindow)
- self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 21))
- self.menubar.setObjectName("menubar")
- MainWindow.setMenuBar(self.menubar)
- self.statusbar = QtWidgets.QStatusBar(MainWindow)
- self.statusbar.setObjectName("statusbar")
- MainWindow.setStatusBar(self.statusbar)
-
- self.retranslateUi(MainWindow)
- QtCore.QMetaObject.connectSlotsByName(MainWindow)
-
- def retranslateUi(self, MainWindow):
- _translate = QtCore.QCoreApplication.translate
- MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
diff --git a/src/ui/Ui_semesterapparat_ui.ts b/src/ui/Ui_semesterapparat_ui.ts
deleted file mode 100644
index 69b16be..0000000
--- a/src/ui/Ui_semesterapparat_ui.ts
+++ /dev/null
@@ -1,232 +0,0 @@
-
-
-
Setup für das Semesterapparatsprogram.
\n' - 'Im Anschluss werden wichtige Einstellungen gesetzt, welche auch im späteren Verlauf verändert werden können.
\n' - 'Setup f\u00fcr das Semesterapparatsprogram.
\n' - 'Im Anschluss werden wichtige Einstellungen gesetzt, welche auch im sp\u00e4teren Verlauf ver\u00e4ndert werden k\u00f6nnen.
\n' - '