From f84c030eea906bc8be8307dd27ee0e824588cd46 Mon Sep 17 00:00:00 2001 From: WorldTeacher Date: Tue, 10 Dec 2024 11:24:04 +0100 Subject: [PATCH] feat: add documentation for ELSA and extend functionality, include new icons and update semester logic --- docs/citing.md | 2 + docs/elsa.md | 25 +++++++ docs/extend.md | 12 ++++ docs/images/elsa_data.png | Bin 0 -> 11530 bytes docs/images/elsa_docs.png | Bin 0 -> 5011 bytes docs/images/elsa_main.png | Bin 0 -> 26946 bytes docs/images/elsa_stats_graph.png | Bin 0 -> 6784 bytes docs/images/elsa_stats_table.png | Bin 0 -> 4490 bytes docs/images/extend.png | Bin 0 -> 8085 bytes docs/images/icon_cal.png | Bin 0 -> 382 bytes docs/search.md | 12 +++- icons/icons.yaml | 5 +- icons/person_add.svg | 1 + src/backend/database.py | 111 +++++++++++++++++++++++-------- src/backend/semester.py | 9 ++- src/logic/dataclass.py | 5 ++ src/logic/threads_autoadder.py | 6 +- 17 files changed, 149 insertions(+), 39 deletions(-) create mode 100644 docs/citing.md create mode 100644 docs/elsa.md create mode 100644 docs/extend.md create mode 100644 docs/images/elsa_data.png create mode 100644 docs/images/elsa_docs.png create mode 100644 docs/images/elsa_main.png create mode 100644 docs/images/elsa_stats_graph.png create mode 100644 docs/images/elsa_stats_table.png create mode 100644 docs/images/extend.png create mode 100644 docs/images/icon_cal.png create mode 100644 icons/person_add.svg diff --git a/docs/citing.md b/docs/citing.md new file mode 100644 index 0000000..54d5d56 --- /dev/null +++ b/docs/citing.md @@ -0,0 +1,2 @@ +# Zitieren + diff --git a/docs/elsa.md b/docs/elsa.md new file mode 100644 index 0000000..2eec8c6 --- /dev/null +++ b/docs/elsa.md @@ -0,0 +1,25 @@ +# ELSA + +![ELSA](images/elsa_main.png) + +## ELSA anlegen +Um einen ELSA zu erstellen, muss der Knopf **Neuer Auftrag** gedrückt werden. Das Feld *Auftragsdaten* wird zum bearbeiten freigeschaltet, der Fokus wird automatisch auf das Feld **Prof.** gesetzt. + +Hier werden automatisch alle bereits vorhandenen Professoren der Semesterapparate eingetragen. Sollte der Professor noch keinen Apparat haben, so kann der Name manuell eingetragen werden. Die ELSA Profs werden in einer anderen Tabelle der Datenbank gespeichert, als die Professoren der Semesterapparate. Deshalb kann hier keine [Mail](mail.md) an den Professor geschickt werden. + +### Dokumente hinzufügen + +![Dokumenttabelle](images/elsa_docs.png) + +Um den ELSA zu speichern, müssen alle Felder ausgefüllt sein. Nach dem Speichern wird der ELSA in der Tabelle angezeigt. Über das Icon ![Icon](images/icon_cal.png) können der aktuelle Tag und das aktuelle Semester eingetragen werden. + +Hat der Professor ein passendes Formular geliefert, so kann dieses über den Knopf **Dokument hinzufügen** hinzugefügt werden. Das Dokument wird in der Datenbank gespeichert und kann über den Knopf **Dokument öffnen** geöffnet werden. Über den Knopf **Medien aus Dokument hinzufügen** werden alle erkannten Medien aus dem Dokument in die Tabelle eingetragen und können zitiert werden. + +!!! Info + Durch den Klick auf den Knopf **Medien aus Dokument hinzufügen** wird der Auftrag automatisch gespeichert. + +### Einträge zitieren + +Da alle gescannten Dokumente später auf Illias hochgeladen werden, gibt es die Funktion **Eintrag zitieren**. Für diese Funktion muss ein Eintrag in der Tabelle ausgewählt werden. Über den Knopf **Eintrag zitieren** wird ein Dialog geöffnet, in dem der Eintrag zitiert werden kann. +Genauere Beschreibung: [Zitieren](citing.md) + diff --git a/docs/extend.md b/docs/extend.md new file mode 100644 index 0000000..abe685b --- /dev/null +++ b/docs/extend.md @@ -0,0 +1,12 @@ +# Verlängerung + +Ein Dialog zum Verlängern eines Apparates. + +![Verlängerung](images/extend.png) + +Zum Verlängern muss ein Semester ausgewählt, und ein Jahr eingetragen sein. Die Checkbox für den Dauerapparat kann angekreuzt werden, um den Apparat als Dauerapparat zu markieren. + +!!! Info "Info Dauerapparat" + Damit der Apparat als Dauerapparat verlängert werden kann, muss ein Semester angegeben werden. + +Nach dem Speichern wird das Semester automatisch angepasst und in den entsprechenden Tabellen angezeigt. \ No newline at end of file diff --git a/docs/images/elsa_data.png b/docs/images/elsa_data.png new file mode 100644 index 0000000000000000000000000000000000000000..be171fd5272eba0ad6831d1d16c6293131273168 GIT binary patch literal 11530 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 literal 0 HcmV?d00001 diff --git a/docs/images/elsa_main.png b/docs/images/elsa_main.png new file mode 100644 index 0000000000000000000000000000000000000000..57333eeac757c97d565ae1da6acf6e3493345ce6 GIT binary patch literal 26946 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 literal 0 HcmV?d00001 diff --git a/docs/images/elsa_stats_graph.png b/docs/images/elsa_stats_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..575b20dab878e51b75a97ec6e8f6c9407b347479 GIT binary patch literal 6784 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 b8|0*!pk@?_2A>_wW1X{c+Y_=j?U%K4+iv+vm4W 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 literal 0 HcmV?d00001 diff --git a/docs/images/icon_cal.png b/docs/images/icon_cal.png new file mode 100644 index 0000000000000000000000000000000000000000..ed73d0c7bfc63a35902ec8d0a910766d287f32eb GIT binary patch literal 382 zcmV-^0fGLBP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0TW3?K~zXf?UPN5 zgfI+- \ No newline at end of file diff --git a/src/backend/database.py b/src/backend/database.py index b5873ce..669ce69 100644 --- a/src/backend/database.py +++ b/src/backend/database.py @@ -11,7 +11,6 @@ from omegaconf import OmegaConf from src.backend.db import ( CREATE_ELSA_FILES_TABLE, CREATE_ELSA_MEDIA_TABLE, - CREATE_ELSA_PROF_TABLE, CREATE_ELSA_TABLE, CREATE_TABLE_APPARAT, CREATE_TABLE_APPKONTOS, @@ -1203,7 +1202,8 @@ class Database: Returns: list[str]: a list of all the roles """ - return self.query_db("SELECT role FROM user") + roles = self.query_db("SELECT role FROM user") + return [i[0] for i in roles] def checkUsername(self, user) -> bool: """a check to see if the username is already present in the database @@ -1311,26 +1311,29 @@ class Database: ) # ELSA - def createElsaProf(self, name): - """create a new professor in the database for the ELSA system - Args: - name (str): the name of the professor - """ - self.query_db("INSERT INTO elsa_prof (name) VALUES (?)", (name,)) - - def createElsaApparat(self, date, prof_id, semester): + def createElsaApparat(self, date, prof_id, semester) -> int: """create a new apparat in the database for the ELSA system Args: date (str): the name of the apparat prof_id (int): the id of the professor semester (str): the semester the apparat is created in + + Returns: + int: the id of the apparat """ self.query_db( "INSERT OR IGNORE INTO elsa (date, prof_id, semester) VALUES (?,?,?)", (date, prof_id, semester), ) + # get the id of the apparat + apparat_id = self.query_db( + "SELECT id FROM elsa WHERE date=? AND prof_id=? AND semester=?", + (date, prof_id, semester), + one=True, + )[0] + return apparat_id def updateElsaApparat(self, date, prof_id, semester, elsa_id): """update an ELSA apparat in the database @@ -1446,9 +1449,13 @@ class Database: Returns: int: the id of the ELSA apparat """ + prof_id = self.getElsaProfId(prof) + if prof_id is None: + return None + data = self.query_db( "SELECT id FROM elsa WHERE prof_id=? AND semester=? AND date=?", - (prof, semester, date), + (prof_id, semester, date), one=True, ) if data is None: @@ -1497,22 +1504,7 @@ class Database: if data: return data[0][0] else: return None - - def createElsaProf(self, profname)-> int: - pId = self.getElsaProfId(profname) - if pId: - return pId - query = f"INSERT INTO elsa_prof (fullname) VALUES ('{profname}')" - self.query_db(query) - return self.getElsaProfId(profname) - - def getElsaProf(self, prof_id)->str: - query = f"SELECT fullname FROM elsa_prof WHERE id = '{prof_id}'" - data = self.query_db(query) - if data: - return data[0][0] - else: return None - + def getElsaProfs(self)->list[str]: query = f"SELECT fullname FROM elsa_prof" data = self.query_db(query) @@ -1521,6 +1513,14 @@ class Database: else: return [] def getProfId(self, profdata: dict|Prof): + """Get the prof ID based on the profdata + + Args: + profdata (dict | Prof): either a dictionary containing the prof data or a Prof object + + Returns: + int | None: The id of the prof or None if not found + """ conn = self.connect() cursor = conn.cursor() if isinstance(profdata, Prof): @@ -1557,8 +1557,61 @@ class Database: if result: return Prof().from_tuple(result) else: return Prof() - def getProfNameByApparat(self, apprarat_id): - query = f"SELECT prof_id from semesterapparat WHERE appnr = '{apprarat_id}'" + + def getProfIDByApparat(self, apprarat_id): + """Get the prof id based on the semesterapparat id from the database + + Args: + apprarat_id (int): Number of the apparat + + Returns: + int | None: The id of the prof or None if not found + """ + query = f"SELECT prof_id from semesterapparat WHERE id = '{apprarat_id}' and deletion_status = 0" + data = self.query_db(query) + if data: + return data[0][0] + else: + return None + + def copyBookToApparat(self, book_id, apparat): + # get book data + new_apparat_id = apparat + new_prof_id = self.getProfIDByApparat(new_apparat_id) + query = f""" + INSERT INTO media (bookdata, app_id, prof_id, deleted, available, reservation) + SELECT + bookdata, + '{new_apparat_id}', + '{new_prof_id}', + 0, + available, + reservation + FROM media + where id = '{book_id}'""" + connection = self.connect() + cursor = connection.cursor() + cursor.execute(query) + connection.commit() + connection.close() + + def moveBookToApparat(self, book_id, appratat): + """Move the book to the new apparat + + Args: + book_id (int): the ID of the book + appratat (int): the ID of the new apparat + """ + # get book data + query = f"UPDATE media SET app_id = '{appratat}' WHERE id = '{book_id}'" + connection = self.connect() + cursor = connection.cursor() + cursor.execute(query) + connection.commit() + connection.close() + + def getApparatNameByAppNr(self, appnr): + query = f"SELECT name FROM semesterapparat WHERE appnr = '{appnr}' and deletion_status = 0" data = self.query_db(query) if data: return data[0][0] diff --git a/src/backend/semester.py b/src/backend/semester.py index f848087..379621b 100644 --- a/src/backend/semester.py +++ b/src/backend/semester.py @@ -5,6 +5,7 @@ def generateSemesterByDate(next:bool = False): currentYear = datetime.datetime.now().year currentYear = int(str(currentYear)[-2:]) month = datetime.datetime.now().month + # month = month + 1 if next: month += 1 if month > 12: @@ -13,7 +14,7 @@ def generateSemesterByDate(next:bool = False): if month >= 4 and month <= 9: return "SoSe " + str(currentYear) else: - if month == 10 or month == 11: + if month == any([10, 11, 12]): return f"WiSe {currentYear}/{currentYear+1}" else: return f"WiSe {currentYear-1}/{currentYear}" @@ -38,4 +39,8 @@ def generateSemesterByOffset(offset): else: return f"WiSe {currentYear+1}/{currentYear+2}" else: - return f"WiSe {currentYear+offset//2}/{currentYear+1+offset//2}" \ No newline at end of file + return f"WiSe {currentYear+offset//2}/{currentYear+1+offset//2}" + + +if __name__ == "__main__": + print(generateSemesterByDate(next=True)) \ No newline at end of file diff --git a/src/logic/dataclass.py b/src/logic/dataclass.py index f7f51a1..3720269 100644 --- a/src/logic/dataclass.py +++ b/src/logic/dataclass.py @@ -30,6 +30,11 @@ class Prof: setattr(self, "telnr", data[6]) return self + def name(self, comma=False): + if comma: + return f"{self.lastname}, {self.firstname}" + return f"{self.lastname} {self.firstname}" + @dataclass class ApparatData: diff --git a/src/logic/threads_autoadder.py b/src/logic/threads_autoadder.py index 4ba2fb1..231d131 100644 --- a/src/logic/threads_autoadder.py +++ b/src/logic/threads_autoadder.py @@ -33,15 +33,11 @@ class AutoAdder(QThread): item = 0 for entry in self.data: try: - # webdata = WebRequest().get_ppn(entry).get_data() - # bd = BibTextTransformer("ARRAY").get_data(webdata).return_data() - # bd.signature = entry + self.updateSignal.emit(item) self.setTextSignal.emit(entry) - # qsleep item += 1 self.progress.emit(item) - # print(item, len(self.data)) time.sleep(1) except Exception as e: