Merge dev to main, nearing completion #6
28
README.md
28
README.md
@@ -1,3 +1,27 @@
|
||||
# Semesterapparate
|
||||
# SemesterapparatsManager
|
||||
|
||||
this repo will be used to create a GUI application to manage the semesterapparate of the PH Freiburg.
|
||||
SemesterapparatsManager is a graphical tool for managing semester apparatuses in the University of Education Freiburg. It allows the users to manage the semester apparatuses in a user-friendly way. It's functions include management of physical and digital semester apparatuses, as well as creating the citations for the digital files of the digital semester apparatuses. For that it uses Zotero, an open source reference management software. The semester apparatuses are stored in a SQLite database, which is created and managed by the SemesterapparatsManager. The SemesterapparatsManager is written in Python and uses the PyQt6 library for the graphical user interface
|
||||
|
||||
|
||||
## Features
|
||||
- Manage physical semester apparatuses
|
||||
- Add semester apparatuses
|
||||
- Edit semester apparatuses
|
||||
- Delete semester apparatuses
|
||||
- Extend semester apparatuses
|
||||
- Notify professors about semester apparatuses creation or deletion
|
||||
- Add messages to all semester apparatuses, or an individual semester apparatus
|
||||
- Manage digital semester apparatuses
|
||||
- Use text parsing to extract information from the submitted form and create the scans
|
||||
- if a book is used multiple parts of a book are used, it can be split into the parts
|
||||
- Create the matching citations for the files
|
||||
- Statistics and Search
|
||||
- Search semester apparatuses by various criteria
|
||||
- Show statistics about the semester apparatuses creation and deletion
|
||||
- Edit user data
|
||||
|
||||
|
||||
## Images
|
||||
|
||||

|
||||

|
||||
BIN
docs/images/statistics.png
Normal file
BIN
docs/images/statistics.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -12,7 +12,7 @@ from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
from PyQt6.QtCore import QThread
|
||||
from PyQt6.QtGui import QRegularExpressionValidator
|
||||
|
||||
from src import Icon, logger
|
||||
from src import Icon, logger, settings
|
||||
from src.backend import Database, BookGrabber, AvailChecker, DocumentationThread
|
||||
from src.backend.semester import Semester
|
||||
from src.backend.create_file import recreateFile
|
||||
@@ -241,7 +241,8 @@ class Ui(Ui_Semesterapparat):
|
||||
"Mit dem Klick auf Okay wird eine Übersicht aller aktiven Semesterapparate erstellt und an den FollowME Drucker gesendet. Es kann bis zu 10 Minuten dauern, bis das document im Drucker angezeigt wird",
|
||||
"document erstellen?",
|
||||
)
|
||||
if result == QtWidgets.QDialog.DialogCode.Accepted:
|
||||
logger.debug(f"Result: {result}")
|
||||
if result == 1:
|
||||
# print("Creating document")
|
||||
apparats = self.apparats
|
||||
apps = []
|
||||
@@ -250,15 +251,19 @@ class Ui(Ui_Semesterapparat):
|
||||
data = (apparat[4], f"{prof.lastname} ({apparat[1]})")
|
||||
apps.append(data)
|
||||
# print(apps)
|
||||
logger.info("Using apparats: {}", apps)
|
||||
doc = SemesterDocument(
|
||||
semester=Semester(),
|
||||
semester=Semester().value,
|
||||
filename="Semesterapparate",
|
||||
apparats=apps,
|
||||
full=True,
|
||||
config=settings,
|
||||
)
|
||||
doc.make_document()
|
||||
doc.create_pdf()
|
||||
doc.print_document()
|
||||
doc.cleanup()
|
||||
# doc.make_document()
|
||||
# doc.create_pdf()
|
||||
# doc.print_document()
|
||||
# doc.cleanup()
|
||||
# logger.info("Document created and sent to printer")
|
||||
|
||||
# kill thread after execution done
|
||||
|
||||
|
||||
@@ -6,22 +6,57 @@ from docx.oxml import OxmlElement
|
||||
from docx.oxml.ns import qn
|
||||
import os
|
||||
from os.path import basename
|
||||
from loguru import logger as log
|
||||
import sys
|
||||
|
||||
|
||||
logger = log
|
||||
logger.remove()
|
||||
logger.add("logs/application.log", rotation="1 week", enqueue=True)
|
||||
log.add(
|
||||
f"logs/{datetime.now().strftime('%Y-%m-%d')}.log",
|
||||
rotation="1 day",
|
||||
compression="zip",
|
||||
)
|
||||
|
||||
# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
|
||||
logger.add(sys.stdout)
|
||||
|
||||
|
||||
class SemesterError(Exception):
|
||||
"""Custom exception for semester-related errors."""
|
||||
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
logger.error(message)
|
||||
|
||||
def __str__(self):
|
||||
return f"SemesterError: {self.args[0]}"
|
||||
|
||||
|
||||
class SemesterDocument:
|
||||
def __init__(self, apparats: list[tuple[int, str]], semester: str, filename):
|
||||
assert isinstance(apparats, list), "Apparats must be a list of tuples"
|
||||
assert all(isinstance(apparat, tuple) for apparat in apparats), (
|
||||
def __init__(
|
||||
self,
|
||||
apparats: list[tuple[int, str]],
|
||||
semester: str,
|
||||
filename,
|
||||
config,
|
||||
full: bool = False,
|
||||
):
|
||||
assert isinstance(apparats, list), SemesterError(
|
||||
"Apparats must be a list of tuples"
|
||||
)
|
||||
assert all(isinstance(apparat[0], int) for apparat in apparats), (
|
||||
assert all(isinstance(apparat, tuple) for apparat in apparats), SemesterError(
|
||||
"Apparats must be a list of tuples"
|
||||
)
|
||||
assert all(isinstance(apparat[0], int) for apparat in apparats), SemesterError(
|
||||
"Apparat numbers must be integers"
|
||||
)
|
||||
assert all(isinstance(apparat[1], str) for apparat in apparats), (
|
||||
assert all(isinstance(apparat[1], str) for apparat in apparats), SemesterError(
|
||||
"Apparat names must be strings"
|
||||
)
|
||||
assert isinstance(semester, str), "Semester must be a string"
|
||||
assert "." not in filename and isinstance(filename, str), (
|
||||
assert isinstance(semester, str), SemesterError("Semester must be a string")
|
||||
assert "." not in filename and isinstance(filename, str), SemesterError(
|
||||
"Filename must be a string and not contain an extension"
|
||||
)
|
||||
self.doc = Document()
|
||||
@@ -35,7 +70,17 @@ class SemesterDocument:
|
||||
self.color_red = RGBColor(255, 0, 0)
|
||||
self.color_blue = RGBColor(0, 0, 255)
|
||||
self.filename = filename
|
||||
|
||||
self.settings = config
|
||||
if full:
|
||||
logger.info("Full document generation")
|
||||
self.make_document()
|
||||
logger.info("Document created")
|
||||
self.create_pdf()
|
||||
logger.info("PDF created")
|
||||
self.print_document()
|
||||
logger.info("Document printed")
|
||||
self.cleanup()
|
||||
logger.info("Cleanup done")
|
||||
def set_table_border(self, table):
|
||||
"""
|
||||
Adds a full border to the table.
|
||||
@@ -161,8 +206,8 @@ class SemesterDocument:
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.application import MIMEApplication
|
||||
from email.mime.text import MIMEText
|
||||
from src import settings as config
|
||||
|
||||
config = self.settings
|
||||
smtp = config.mail.smtp_server
|
||||
port = config.mail.port
|
||||
sender_email = config.mail.sender
|
||||
@@ -202,7 +247,7 @@ class SemesterDocument:
|
||||
doc.SaveAs(f"{curdir}/{self.filename}.pdf", FileFormat=17)
|
||||
doc.Close()
|
||||
word.Quit()
|
||||
print("PDF saved")
|
||||
logger.debug("PDF saved")
|
||||
|
||||
def cleanup(self):
|
||||
os.remove(f"{self.filename}.docx")
|
||||
@@ -210,14 +255,15 @@ class SemesterDocument:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
apparat = [(i, f"Item {i}") for i in range(405, 438)]
|
||||
doc = SemesterDocument(
|
||||
apparat,
|
||||
"WiSe 24/25",
|
||||
"semap",
|
||||
)
|
||||
doc.make_document()
|
||||
doc.create_pdf()
|
||||
pass
|
||||
# apparat = [(i, f"Item {i}") for i in range(405, 438)]
|
||||
# doc = SemesterDocument(
|
||||
# apparat,
|
||||
# "WiSe 24/25",
|
||||
# "semap",
|
||||
# )
|
||||
# doc.make_document()
|
||||
# doc.create_pdf()
|
||||
# doc.print_document()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user