fix broken files after faulty update
This commit is contained in:
39
.bumpversion.toml
Normal file
39
.bumpversion.toml
Normal file
@@ -0,0 +1,39 @@
|
||||
[tool.bumpversion]
|
||||
current_version = "0.1.0"
|
||||
parse = """(?x)
|
||||
(?P<major>0|[1-9]\\d*)\\.
|
||||
(?P<minor>0|[1-9]\\d*)\\.
|
||||
(?P<patch>0|[1-9]\\d*)
|
||||
(?:
|
||||
- # dash separator for pre-release section
|
||||
(?P<pre_l>[a-zA-Z-]+) # pre-release label
|
||||
(?P<pre_n>0|[1-9]\\d*) # pre-release version number
|
||||
)? # pre-release section is optional
|
||||
"""
|
||||
serialize = [
|
||||
"{major}.{minor}.{patch}-{pre_l}{pre_n}",
|
||||
"{major}.{minor}.{patch}",
|
||||
]
|
||||
search = "{current_version}"
|
||||
replace = "{new_version}"
|
||||
regex = false
|
||||
ignore_missing_version = false
|
||||
ignore_missing_files = false
|
||||
tag = true
|
||||
sign_tags = false
|
||||
tag_name = "v{new_version}"
|
||||
tag_message = "Bump version: {current_version} → {new_version}"
|
||||
allow_dirty = false
|
||||
commit = true
|
||||
message = "Bump version: {current_version} → {new_version}"
|
||||
commit_args = ""
|
||||
setup_hooks = []
|
||||
pre_commit_hooks = []
|
||||
post_commit_hooks = []
|
||||
[tool.bumpversion.parts.pre_l]
|
||||
values = ["dev", "rc", "final"]
|
||||
optional_value = "final"
|
||||
[[tool.bumpversion.files]]
|
||||
filename = ".version"
|
||||
[[tool.bumpversion.files]]
|
||||
filename = "__init__.py"
|
||||
1
.python-version
Normal file
1
.python-version
Normal file
@@ -0,0 +1 @@
|
||||
3.13
|
||||
0
CHANGELOG.md
Normal file
0
CHANGELOG.md
Normal file
@@ -1,3 +1,3 @@
|
||||
from src import UI
|
||||
from src.ui.userInterface import launch_gui as UI
|
||||
if __name__ == "__main__":
|
||||
UI()
|
||||
UI() #:des
|
||||
@@ -1 +1,2 @@
|
||||
|
||||
from .config import Config
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from typing import Optional
|
||||
from dataclasses import dataclass
|
||||
from omegaconf import OmegaConf, DictConfig
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
Auf dieser Seite gibt es zwei Hauptfunktionen: die Suche und die Statistik. Standardmäßig wird die Statistik geöffnet.
|
||||
|
||||
|
||||
## Statistikbereich
|
||||
|
||||
### Suche
|
||||
@@ -24,6 +25,8 @@ In diesem Bereich kann die Suche nach Semesterapparaten durchgeführt werden. Su
|
||||
Die Suche kann durch Klicken auf den Button **Suchen** gestartet werden. Die Ergebnisse werden in der Tabelle darunter angezeigt.
|
||||
|
||||
### Suchergebnisse
|
||||
!!! Info
|
||||
Der Ergebnisbereich kann über den Vertikalen Slider verschoben werden, um mehr Platz für Tabelle, oder den Graphen zu schaffen. Hierzu mit der Maus auf den Raum zwischen den beiden Bereichen klicken und ziehen.
|
||||

|
||||
|
||||
In diesem Bereich werden die Suchergebnisse angezeigt. Für jeden gefundenen Treffer wird eine Zeile angelegt:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from .config import Icons
|
||||
|
||||
icons = Icons()
|
||||
|
||||
59
icons/config.py
Normal file
59
icons/config.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from omegaconf import OmegaConf, DictConfig
|
||||
from typing import Optional
|
||||
import os
|
||||
import sys
|
||||
|
||||
class Icons:
|
||||
_config: Optional[DictConfig] = None
|
||||
|
||||
def __init__(self):
|
||||
self._config = OmegaConf.load("icons/icons.yaml")
|
||||
self.config_path = "icons/config.yaml"
|
||||
|
||||
def save(self):
|
||||
OmegaConf.save(self._config, self.config_path)
|
||||
|
||||
@property
|
||||
def icons(self):
|
||||
return self._config.icons
|
||||
|
||||
def get_icon(self, name: str):
|
||||
return self.icons[name]
|
||||
|
||||
def set_icon(self, name: str, value: str):
|
||||
self._config.icons[name] = value
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return self._config.icon_path
|
||||
|
||||
@property
|
||||
def colors(self):
|
||||
return self._config.colors
|
||||
|
||||
@colors.setter
|
||||
def colors(self, value):
|
||||
self._config.colors = value
|
||||
|
||||
@property
|
||||
def dark(self):
|
||||
return self._config.colors.dark
|
||||
|
||||
@property
|
||||
def light(self):
|
||||
return self._config.colors.light
|
||||
|
||||
@property
|
||||
def warning(self):
|
||||
return self._config.colors.warning
|
||||
|
||||
@property
|
||||
def success(self):
|
||||
return self._config.colors.success
|
||||
|
||||
def set_color(self, name: str, value: str):
|
||||
self._config.colors[name] = value
|
||||
|
||||
@icons.setter
|
||||
def icons(self, value):
|
||||
self._config.icons = value
|
||||
@@ -1,28 +0,0 @@
|
||||
icon_path: icons/
|
||||
|
||||
dark_color: '#75FB4Cmail'
|
||||
light_color: '#EA3323'
|
||||
icons:
|
||||
locked: locked.svg
|
||||
logo: logo.ico
|
||||
show_password: visibility_off.svg
|
||||
hide_password: visibility_on.svg
|
||||
settings: settings.svg
|
||||
today: calendar_today.svg
|
||||
save: save.svg
|
||||
edit_note: edit_note.svg
|
||||
warning: warning.svg
|
||||
error: error.svg
|
||||
mail: mail.svg
|
||||
semester: semester.svg
|
||||
template_fail: test_fail.svg
|
||||
offAction: shutdown.svg
|
||||
info: info.svg
|
||||
help: help.svg
|
||||
close: close.svg
|
||||
notification: notification.svg
|
||||
valid_true: check_success.svg
|
||||
valid_false: check_fail.svg
|
||||
edit: edit.svg
|
||||
important_warn : red_warn.svg
|
||||
person: person_add.svg
|
||||
11
mail_vorlagen/test.eml
Normal file
11
mail_vorlagen/test.eml
Normal file
@@ -0,0 +1,11 @@
|
||||
Subject: test new template
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/html; charset="UTF-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">dklfdslködfskfd</p></body></html>
|
||||
6
main.py
6
main.py
@@ -1,6 +1,4 @@
|
||||
from src.logic import userInterface
|
||||
from src.ui.userInterface import launch_gui as UI
|
||||
|
||||
if __name__ == "__main__":
|
||||
userInterface.launch_gui()
|
||||
|
||||
# display_graph()
|
||||
UI()
|
||||
|
||||
33
pyproject.toml
Normal file
33
pyproject.toml
Normal file
@@ -0,0 +1,33 @@
|
||||
[project]
|
||||
name = "semesterapparatsmanager"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"beautifulsoup4>=4.12.3",
|
||||
"bump-my-version>=0.29.0",
|
||||
"chardet>=5.2.0",
|
||||
"darkdetect>=0.8.0",
|
||||
"docx2pdf>=0.1.8",
|
||||
"loguru>=0.7.3",
|
||||
"mkdocs>=1.6.1",
|
||||
"mkdocs-material>=9.5.49",
|
||||
"mkdocs-material-extensions>=1.3.1",
|
||||
"natsort>=8.4.0",
|
||||
"omegaconf>=2.3.0",
|
||||
"pandas>=2.2.3",
|
||||
"pyqt6>=6.8.0",
|
||||
"pyqtgraph>=0.13.7",
|
||||
"python-docx>=1.1.2",
|
||||
"pyzotero>=1.6.4",
|
||||
"ratelimit>=2.2.1",
|
||||
"requests>=2.32.3",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"bump-my-version>=0.29.0",
|
||||
"icecream>=2.1.4",
|
||||
"nuitka>=2.5.9",
|
||||
]
|
||||
12
pytest.ini
Normal file
12
pytest.ini
Normal file
@@ -0,0 +1,12 @@
|
||||
[pytest]
|
||||
# command should be *including --cov to generate coverage report
|
||||
addopts = --cov
|
||||
testpaths = tests
|
||||
python_files = test_*.py
|
||||
; Configuring pytest
|
||||
; More info: https://docs.pytest.org/en/6.2.x/customize.html
|
||||
|
||||
;Logging
|
||||
; DATE FORMAT EXAMPLE: %Y-%m-%d %H:%M:%S
|
||||
; log_cli_format = %(asctime)s %(levelname)-8s %(name)-8s %(message)s
|
||||
; log_cli_date_format = %H:%M:%S
|
||||
@@ -1,11 +1,25 @@
|
||||
__version__ = "1.0.0"
|
||||
__author__ = "Alexander Kirchner"
|
||||
|
||||
import sys
|
||||
from config import Config
|
||||
import os
|
||||
from loguru import logger as log
|
||||
import sys
|
||||
|
||||
settings = Config("config/config.yaml")
|
||||
|
||||
from .utils.icon import Icon
|
||||
|
||||
from .logic.log import MyLogger
|
||||
from .ui.userInterface import launch_gui as UI
|
||||
__version__ = "0.1.0"
|
||||
__author__ = "Alexander Kirchner"
|
||||
|
||||
|
||||
if not os.path.exists("logs"):
|
||||
os.mkdir("logs")
|
||||
# open and close the file to create it
|
||||
logger = log
|
||||
logger.remove()
|
||||
logger.add("logs/application_info.log", rotation="1 week", level="INFO", enqueue=True)
|
||||
logger.add("logs/application_error.log", rotation="1 week", level="ERROR", enqueue=True)
|
||||
logger.add("logs/application_debug.log", rotation="1 week", level="DEBUG", enqueue=True)
|
||||
logger.add("logs/application.log", rotation="1 week", enqueue=True)
|
||||
# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
|
||||
logger.add(sys.stdout)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
from .admin_console import AdminCommands
|
||||
from .create_file import recreateElsaFile, recreateFile
|
||||
from .database import Database
|
||||
from .delete_temp_contents import delete_temp_contents as tempdelete
|
||||
from .semester import generateSemesterByDate, generateSemesterByOffset
|
||||
from .semester import Semester
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import hashlib
|
||||
import random
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from icecream import ic
|
||||
|
||||
from src.backend.database import Database
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ import tempfile
|
||||
from pathlib import Path
|
||||
from src import settings
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
# from icecream import ic
|
||||
from omegaconf import OmegaConf
|
||||
import datetime
|
||||
from src import logger
|
||||
from src.backend.db import (
|
||||
CREATE_ELSA_FILES_TABLE,
|
||||
CREATE_ELSA_MEDIA_TABLE,
|
||||
@@ -22,15 +22,14 @@ from src.backend.db import (
|
||||
CREATE_TABLE_USER,
|
||||
)
|
||||
from src.errors import AppPresentError, NoResultError
|
||||
from src.logic import ApparatData, BookData, Prof, Apparat, ELSA, logger as log
|
||||
from src.logic import ApparatData, BookData, Prof, Apparat, ELSA
|
||||
from src.logic.constants import SEMAP_MEDIA_ACCOUNTS
|
||||
from src.utils import create_blob, dump_pickle, load_pickle
|
||||
from .semester import generateSemesterByDate
|
||||
from icecream import ic
|
||||
from string import ascii_lowercase as lower, digits
|
||||
from .semester import Semester
|
||||
from string import ascii_lowercase as lower, digits, punctuation
|
||||
|
||||
|
||||
ascii_lowercase = lower + digits
|
||||
ascii_lowercase = lower + digits + punctuation
|
||||
# get the line that called the function
|
||||
class Database:
|
||||
database = settings.database
|
||||
@@ -62,7 +61,7 @@ class Database:
|
||||
# print(path)
|
||||
os.makedirs(path)
|
||||
if self.get_db_contents() == []:
|
||||
log.critical("Database does not exist, creating tables")
|
||||
logger.critical("Database does not exist, creating tables")
|
||||
self.create_tables()
|
||||
self.insertSubjects()
|
||||
|
||||
@@ -146,12 +145,12 @@ class Database:
|
||||
"""
|
||||
conn = self.connect()
|
||||
cursor = conn.cursor()
|
||||
log.info(f"Inserting {params} into database with query {query}")
|
||||
logger.debug(f"Inserting {params} into database with query {query}")
|
||||
cursor.execute(query, params)
|
||||
conn.commit()
|
||||
self.close_connection(conn)
|
||||
|
||||
@log.catch
|
||||
@logger.catch
|
||||
def query_db(
|
||||
self, query: str, args: Tuple = (), one: bool = False
|
||||
) -> Union[Tuple, List[Tuple]]:
|
||||
@@ -181,14 +180,14 @@ class Database:
|
||||
# if "INSERT" in query:
|
||||
# log_message = f"Querying database with query {query}"
|
||||
|
||||
log.info(log_message)
|
||||
logger.debug(log_message)
|
||||
try:
|
||||
cursor.execute(query, args)
|
||||
rv = cursor.fetchall()
|
||||
conn.commit()
|
||||
self.close_connection(conn)
|
||||
except sql.OperationalError as e:
|
||||
log.error(f"Error in query: {e}")
|
||||
logger.error(f"Error in query: {e}")
|
||||
return None
|
||||
return (rv[0] if rv else None) if one else rv
|
||||
|
||||
@@ -211,7 +210,7 @@ class Database:
|
||||
t_query = (
|
||||
f"SELECT bookdata FROM media WHERE app_id={app_id} AND prof_id={prof_id}"
|
||||
)
|
||||
log.info(t_query)
|
||||
logger.debug(t_query)
|
||||
# # print(t_query)
|
||||
result = cursor.execute(t_query).fetchall()
|
||||
result = [load_pickle(i[0]) for i in result]
|
||||
@@ -238,7 +237,7 @@ class Database:
|
||||
params = (converted, app_id, prof_id, 0)
|
||||
cursor.execute(query, params)
|
||||
logMessage = f"Added book with signature {bookdata.signature} to database, data: {converted}"
|
||||
log.info(logMessage)
|
||||
logger.info(logMessage)
|
||||
conn.commit()
|
||||
self.close_connection(conn)
|
||||
|
||||
@@ -307,7 +306,7 @@ class Database:
|
||||
list[tuple[BookData, int]]: A list of tuples containing the wrapped Metadata and the id of the book
|
||||
"""
|
||||
rdata = self.query_db("SELECT * FROM media WHERE deleted=0")
|
||||
# ic(rdata, len(rdata))
|
||||
# logger.debug(rdata, len(rdata))
|
||||
mode = 0
|
||||
if len(data) == 1:
|
||||
if "signature" in data.keys():
|
||||
@@ -335,7 +334,7 @@ class Database:
|
||||
and data["title"] in bookdata.title
|
||||
):
|
||||
ret.append((bookdata, app_id, prof_id))
|
||||
# ic(ret)
|
||||
# logger.debug(ret)
|
||||
return ret
|
||||
|
||||
def setAvailability(self, book_id: str, available: str):
|
||||
@@ -514,7 +513,7 @@ class Database:
|
||||
(app_id, prof_id),
|
||||
)
|
||||
|
||||
def getSemersters(self) -> list[str]:
|
||||
def getSemesters(self) -> list[str]:
|
||||
"""Return all the unique semesters in the database
|
||||
|
||||
Returns:
|
||||
@@ -640,7 +639,7 @@ class Database:
|
||||
Args:
|
||||
message_id (str): the id of the message
|
||||
"""
|
||||
log.info(f"Deleting message with id {message_id}")
|
||||
logger.debug(f"Deleting message with id {message_id}")
|
||||
self.query_db("DELETE FROM messages WHERE id=?", (message_id,))
|
||||
|
||||
# Prof data
|
||||
@@ -710,7 +709,6 @@ class Database:
|
||||
(profname.replace(",", ""),),
|
||||
one=True,
|
||||
)
|
||||
print(data)
|
||||
person = Prof()
|
||||
return person.from_tuple(data)
|
||||
|
||||
@@ -770,20 +768,21 @@ class Database:
|
||||
if result is None:
|
||||
raise NoResultError("No result found")
|
||||
apparat = ApparatData()
|
||||
apparat.appname = result[1]
|
||||
apparat.appnr = result[4]
|
||||
apparat.dauerapp = True if result[7] == 1 else False
|
||||
prof_data = self.getProfData(self.getProfNameById(result[2]))
|
||||
apparat.profname = self.getProfNameById(result[2])
|
||||
apparat.prof_mail = prof_data.mail
|
||||
apparat.prof_tel = prof_data.telnr
|
||||
apparat.prof_title = prof_data.title
|
||||
apparat.app_fach = result[3]
|
||||
apparat.erstellsemester = result[5]
|
||||
apparat.semester = result[8]
|
||||
apparat.deleted = result[9]
|
||||
apparat.apparat_adis_id = result[11]
|
||||
apparat.prof_adis_id = result[12]
|
||||
apparat.apparat.id = result[0]
|
||||
apparat.apparat.name = result[1]
|
||||
apparat.apparat.appnr = result[4]
|
||||
apparat.apparat.eternal = True if result[7] == 1 else False
|
||||
apparat.prof = self.getProfData(self.getProfNameById(result[2]))
|
||||
apparat.prof.fullname = self.getProfNameById(result[2])
|
||||
apparat.apparat.prof_id = result[2]
|
||||
|
||||
apparat.apparat.subject = result[3]
|
||||
apparat.apparat.created_semester = result[5]
|
||||
apparat.apparat.extend_until = result[8]
|
||||
apparat.apparat.deleted = result[9]
|
||||
apparat.apparat.apparat_id_adis = result[11]
|
||||
apparat.apparat.prof_id_adis = result[12]
|
||||
apparat.apparat.konto = result[13]
|
||||
return apparat
|
||||
|
||||
def getUnavailableApparatNumbers(self) -> List[int]:
|
||||
@@ -796,7 +795,7 @@ class Database:
|
||||
"SELECT appnr FROM semesterapparat WHERE deletion_status=0"
|
||||
)
|
||||
numbers = [i[0] for i in numbers]
|
||||
log.info(f"Currently used apparat numbers: {numbers}")
|
||||
logger.info(f"Currently used apparat numbers: {numbers}")
|
||||
return numbers
|
||||
|
||||
def setNewSemesterDate(self, app_id: Union[str, int], newDate, dauerapp=False):
|
||||
@@ -850,21 +849,22 @@ class Database:
|
||||
Returns:
|
||||
Optional[int]: the id of the apparat
|
||||
"""
|
||||
ic(apparat)
|
||||
prof = self.getProfByName(apparat.prof_details.fullname)
|
||||
prof_id = prof.id
|
||||
ic(prof_id, apparat.profname)
|
||||
logger.debug(apparat)
|
||||
app = apparat.apparat
|
||||
prof = apparat.prof
|
||||
present_prof = self.getProfByName(prof.name())
|
||||
prof_id = present_prof.id
|
||||
logger.debug(present_prof)
|
||||
|
||||
app_id = self.getApparatId(apparat.appname)
|
||||
app_id = self.getApparatId(app.name)
|
||||
if app_id:
|
||||
return AppPresentError(app_id)
|
||||
if not prof_id:
|
||||
print("prof id not present, creating prof with data", apparat.prof_details)
|
||||
prof_id = self.createProf(apparat.prof_details)
|
||||
# self.getProfId(apparat.profname)
|
||||
ic(prof_id)
|
||||
query = f"INSERT OR IGNORE INTO semesterapparat (appnr, name, erstellsemester, dauer, prof_id, fach,deletion_status,konto) VALUES ('{apparat.appnr}', '{apparat.appname}', '{apparat.semester}', '{apparat.dauerapp}', {prof_id}, '{apparat.app_fach}', '{0}', '{SEMAP_MEDIA_ACCOUNTS[apparat.appnr]}')"
|
||||
log.info(query)
|
||||
logger.debug("prof id not present, creating prof with data", prof)
|
||||
prof_id = self.createProf(prof)
|
||||
logger.debug(prof_id)
|
||||
query = f"INSERT OR IGNORE INTO semesterapparat (appnr, name, erstellsemester, dauer, prof_id, fach,deletion_status,konto) VALUES ('{app.appnr}', '{app.name}', '{app.created_semester}', '{app.eternal}', {prof_id}, '{app.subject}', '{0}', '{SEMAP_MEDIA_ACCOUNTS[app.appnr]}')"
|
||||
logger.debug(query)
|
||||
self.query_db(query)
|
||||
return None
|
||||
def getApparatsByProf(self, prof_id: Union[str, int]) -> list[tuple]:
|
||||
@@ -934,7 +934,7 @@ class Database:
|
||||
"""
|
||||
conn = self.connect()
|
||||
cursor = conn.cursor()
|
||||
semesters = self.getSemersters()
|
||||
semesters = self.getSemesters()
|
||||
created = []
|
||||
deleted = []
|
||||
for semester in semesters:
|
||||
@@ -946,7 +946,6 @@ class Database:
|
||||
deleted.append(result[0])
|
||||
# store data in a tuple
|
||||
ret = []
|
||||
e_tuple = ()
|
||||
for sem in semesters:
|
||||
e_tuple = (
|
||||
sem,
|
||||
@@ -957,17 +956,16 @@ class Database:
|
||||
self.close_connection(conn)
|
||||
return ret
|
||||
|
||||
def deleteApparat(self, app_id: Union[str, int]):
|
||||
def deleteApparat(self, app_id: Union[str, int], semester):
|
||||
"""Delete an apparat from the database
|
||||
|
||||
Args:
|
||||
app_id (Union[str, int]): the id of the apparat
|
||||
semester (str): the semester the apparat should be deleted from
|
||||
"""
|
||||
today = datetime.datetime.now().strftime("%Y-%m-%d")
|
||||
self.query_db(
|
||||
"UPDATE semesterapparat SET deletion_status=1, deleted_date=? WHERE appnr=?",
|
||||
(today, app_id),
|
||||
(semester, app_id),
|
||||
)
|
||||
|
||||
def isEternal(self, id):
|
||||
@@ -1007,15 +1005,15 @@ class Database:
|
||||
"""
|
||||
query = "UPDATE semesterapparat SET name = ?, fach = ?, dauer = ?, prof_id = ?, prof_id_adis = ?, apparat_id_adis = ? WHERE appnr = ?"
|
||||
params = (
|
||||
apparat_data.appname,
|
||||
apparat_data.app_fach,
|
||||
apparat_data.dauerapp,
|
||||
self.getProfData(apparat_data.prof_details.fullname).id,
|
||||
apparat_data.prof_adis_id,
|
||||
apparat_data.apparat_adis_id,
|
||||
apparat_data.appnr,
|
||||
apparat_data.apparat.name,
|
||||
apparat_data.apparat.subject,
|
||||
apparat_data.apparat.eternal,
|
||||
self.getProfData(apparat_data.prof.fullname).id,
|
||||
apparat_data.apparat.prof_id_adis,
|
||||
apparat_data.apparat.apparat_id_adis,
|
||||
apparat_data.apparat.appnr,
|
||||
)
|
||||
log.info(f"Updating apparat with query {query} and params {params}")
|
||||
logger.debug(f"Updating apparat with query {query} and params {params}")
|
||||
self.query_db(query, params)
|
||||
|
||||
def checkApparatExists(self, app_name: str):
|
||||
@@ -1067,7 +1065,8 @@ class Database:
|
||||
Returns:
|
||||
list: the result of the query
|
||||
"""
|
||||
ic(query)
|
||||
logger.debug(query)
|
||||
logger.debug(f"Query: {query}")
|
||||
conn = self.connect()
|
||||
cursor = conn.cursor()
|
||||
result = cursor.execute(query).fetchall()
|
||||
@@ -1080,15 +1079,15 @@ class Database:
|
||||
result_a = tuple(result_a)
|
||||
result[result.index(orig_value)] = result_a
|
||||
self.close_connection(conn)
|
||||
log.info(f"Query result: {result}")
|
||||
logger.debug(f"Query result: {result}")
|
||||
return result
|
||||
|
||||
if "deletable" in kwargs.keys():
|
||||
query = f"""SELECT * FROM semesterapparat
|
||||
WHERE deletion_status=0 AND dauer=0 AND
|
||||
(
|
||||
(erstellsemester!='{kwargs['deletesemester']}' AND verlängerung_bis IS NULL) OR
|
||||
(erstellsemester!='{kwargs['deletesemester']}' AND verlängerung_bis!='{kwargs['deletesemester']}' AND verlängerung_bis!='{generateSemesterByDate(True)}')
|
||||
(erstellsemester!='{kwargs["deletesemester"]}' AND verlängerung_bis IS NULL) OR
|
||||
(erstellsemester!='{kwargs["deletesemester"]}' AND verlängerung_bis!='{kwargs["deletesemester"]}' AND verlängerung_bis!='{Semester()}')
|
||||
)"""
|
||||
return __query(query)
|
||||
if "dauer" in kwargs.keys():
|
||||
@@ -1119,8 +1118,10 @@ class Database:
|
||||
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]
|
||||
logger.info(f"Query before: {query}")
|
||||
query = query.strip()
|
||||
query = query[:-4]
|
||||
logger.info(f"Query after: {query}")
|
||||
# check if query ends with lowercase letter or a '. if not, remove last symbol and try again
|
||||
while query[-1] not in ascii_lowercase and query[-1] != "'":
|
||||
query = query[:-1]
|
||||
@@ -1471,22 +1472,19 @@ class Database:
|
||||
)
|
||||
###
|
||||
|
||||
|
||||
|
||||
def createProf(self, profdata:Prof):
|
||||
print("createProf")
|
||||
ic(profdata)
|
||||
def createProf(self, profdata: Prof):
|
||||
logger.debug(profdata)
|
||||
conn = self.connect()
|
||||
cursor = conn.cursor()
|
||||
fname = profdata.firstname#profdata["profname"].split(", ")[1].strip()
|
||||
lname = profdata.lastname#profdata["profname"].split(", ")[0].strip()
|
||||
fname = profdata.firstname
|
||||
lname = profdata.lastname
|
||||
fullname = f"{lname} {fname}"
|
||||
mail = profdata.mail#profdata["prof_mail"]
|
||||
telnr = profdata.telnr#profdata["prof_tel"]
|
||||
title = profdata.title #profdata["title"]
|
||||
mail = profdata.mail
|
||||
telnr = profdata.telnr
|
||||
title = profdata.title
|
||||
|
||||
query = f"INSERT INTO prof (fname, lname, fullname, mail, telnr,titel) VALUES ('{fname}','{lname}','{fullname}','{mail}','{telnr}','{title}')"
|
||||
log.info(query)
|
||||
logger.debug(query)
|
||||
cursor.execute(query)
|
||||
|
||||
conn.commit()
|
||||
@@ -1519,7 +1517,7 @@ class Database:
|
||||
conn = self.connect()
|
||||
cursor = conn.cursor()
|
||||
if isinstance(profdata, Prof):
|
||||
fullname = profdata.fullname
|
||||
fullname = profdata.name()
|
||||
else:
|
||||
name = profdata["profname"]
|
||||
if ","in name:
|
||||
@@ -1529,7 +1527,7 @@ class Database:
|
||||
else:
|
||||
fullname = profdata["profname"]
|
||||
query = f"SELECT id FROM prof WHERE fullname = '{fullname}'"
|
||||
log.info(query)
|
||||
logger.debug(query)
|
||||
|
||||
cursor.execute(query)
|
||||
result = cursor.fetchone()
|
||||
@@ -1546,7 +1544,7 @@ class Database:
|
||||
conn = self.connect()
|
||||
cursor = conn.cursor()
|
||||
query = f"SELECT * FROM prof WHERE fullname = '{fullname}'"
|
||||
log.info(query)
|
||||
logger.debug(query)
|
||||
|
||||
result = cursor.execute(query).fetchone()
|
||||
if result:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
CREATE_TABLE_APPARAT = """CREATE TABLE semesterapparat (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name TEXT,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from src import database
|
||||
|
||||
from src import settings
|
||||
|
||||
database = settings.database
|
||||
|
||||
def delete_temp_contents():
|
||||
"""
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import pickle
|
||||
from typing import Any, ByteString
|
||||
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
import datetime
|
||||
from src.logic.log import logger
|
||||
from src import logger
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class Semester:
|
||||
logger.debug("Semester class loaded")
|
||||
|
||||
_year: int | None = datetime.datetime.now().year
|
||||
_year: int | None = str(datetime.datetime.now().year)[2:]
|
||||
_semester: str | None = None
|
||||
_month: int | None = datetime.datetime.now().month
|
||||
value: str = None
|
||||
logger.debug(f"Got values year:{_year}, semester:{_semester}, month:{_month}")
|
||||
|
||||
def __post_init__(self):
|
||||
logger.debug(
|
||||
f"Got values post_init year:{self._year}, semester:{self._semester}, month:{self._month}"
|
||||
)
|
||||
|
||||
if isinstance(self._year, str):
|
||||
self._year = int(self._year)
|
||||
if self._year is None:
|
||||
self._year = datetime.datetime.now().year
|
||||
self._year = datetime.datetime.now().year[2:]
|
||||
if self._month is None:
|
||||
self._month = datetime.datetime.now().month
|
||||
if self._semester is None:
|
||||
@@ -37,11 +34,7 @@ class Semester:
|
||||
@logger.catch
|
||||
def computeValue(self):
|
||||
# year is only last two digits
|
||||
year = str(self._year)[2:]
|
||||
year = int(year)
|
||||
logger.debug(
|
||||
f"Year is {year}, month is {self._month}, semester is {self._semester}"
|
||||
)
|
||||
year = self._year
|
||||
if self._semester == "WiSe":
|
||||
if self._month < 4:
|
||||
valueyear = str(year - 1) + "/" + str(year)
|
||||
@@ -60,25 +53,63 @@ class Semester:
|
||||
str: the new semester value
|
||||
"""
|
||||
assert isinstance(value, int), "Value must be an integer"
|
||||
logger.debug(f"Offsetting semester by {value}")
|
||||
if value == 0:
|
||||
return self
|
||||
if value > 0:
|
||||
if value % 2 == 0:
|
||||
return Semester(self._year + value // 2, self._semester)
|
||||
return Semester(
|
||||
self._year - value // 2, self._semester - value // 2 + 1
|
||||
)
|
||||
else:
|
||||
semester = self._semester
|
||||
semester = "SoSe" if semester == "WiSe" else "WiSe"
|
||||
logger.debug(f"Semester is {semester}")
|
||||
return Semester(self._year + value // 2, semester)
|
||||
else:
|
||||
if value % 2 == 0:
|
||||
return Semester(self._year - value // 2, self._semester)
|
||||
return Semester(self.year + value // 2, self._semester)
|
||||
else:
|
||||
semester = self._semester
|
||||
semester = "SoSe" if semester == "WiSe" else "WiSe"
|
||||
return Semester(self._year + value // 2, semester)
|
||||
|
||||
def isPastSemester(self, semester) -> bool:
|
||||
"""Checks if the current Semester is a past Semester compared to the given Semester
|
||||
|
||||
Args:
|
||||
semester (str): The semester to compare to
|
||||
|
||||
Returns:
|
||||
bool: True if the current semester is in the past, False otherwise
|
||||
"""
|
||||
if self.year < semester.year:
|
||||
return True
|
||||
if self.year == semester.year:
|
||||
if self.semester == "WiSe" and semester.semester == "SoSe":
|
||||
return True
|
||||
return False
|
||||
|
||||
def isFutureSemester(self, semester: "Semester") -> bool:
|
||||
"""Checks if the current Semester is a future Semester compared to the given Semester
|
||||
|
||||
Args:
|
||||
semester (str): The semester to compare to
|
||||
|
||||
Returns:
|
||||
bool: True if the current semester is in the future, False otherwise
|
||||
"""
|
||||
if self.year > semester.year:
|
||||
return True
|
||||
if self.year == semester.year:
|
||||
if self.semester == "SoSe" and semester.semester == "WiSe":
|
||||
return True
|
||||
return False
|
||||
|
||||
def from_string(self, val):
|
||||
self.value = val
|
||||
self._year = int(val[-2:])
|
||||
self._semester = val[:4]
|
||||
return self
|
||||
|
||||
@property
|
||||
def next(self):
|
||||
return self.offset(1)
|
||||
@@ -86,3 +117,11 @@ class Semester:
|
||||
@property
|
||||
def previous(self):
|
||||
return self.offset(-1)
|
||||
|
||||
@property
|
||||
def year(self):
|
||||
return self._year
|
||||
|
||||
@property
|
||||
def semester(self):
|
||||
return self._semester
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
import yaml
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
class NoResultError(Exception):
|
||||
def __init__(self, message):
|
||||
self.message = f"The query: {message} returned no results"
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
|
||||
# import basic error classes
|
||||
from .DatabaseErrors import *
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from .log import MyLogger, logger
|
||||
|
||||
from .dataclass import ApparatData, BookData, Prof, Apparat, ELSA
|
||||
from .thread_bookgrabber import BookGrabber
|
||||
from .threads_autoadder import AutoAdder
|
||||
from .threads_availchecker import AvailChecker
|
||||
from .c_sort import custom_sort
|
||||
from .c_sort import custom_sort, sort_semesters_list
|
||||
from .constants import APP_NRS, PROF_TITLES, SEMAP_MEDIA_ACCOUNTS
|
||||
from .csvparser import csv_to_list
|
||||
from .wordparser import elsa_word_to_csv, word_docx_to_csv
|
||||
|
||||
@@ -1,59 +1,86 @@
|
||||
from typing import List, Tuple
|
||||
|
||||
from natsort import natsorted
|
||||
|
||||
|
||||
def custom_sort(unsorted: List[Tuple[str, int, int]]) -> List[Tuple[str, int, int]]:
|
||||
"""Sort a list of semesters in the format "SoSe n" and "WiSe n/n+1" in the correct order.
|
||||
Where n == year in 2 digit format
|
||||
|
||||
Args:
|
||||
----
|
||||
unsorted (list[tuple]): List of semesters in the format "SoSe n" and "WiSe n/n+1"
|
||||
|
||||
Returns:
|
||||
-------
|
||||
ret (list[tuple]): Sorted list in correct order of WiSe n/n+1 and SoSe n
|
||||
def parse_semester(semester: str):
|
||||
"""
|
||||
summer = natsorted([i for i in unsorted if "SoSe" in i[0]])
|
||||
winter = natsorted([i for i in unsorted if "WiSe" in i[0]])
|
||||
summer = natsorted(summer, key=lambda x: x[0])
|
||||
winter = natsorted(winter, key=lambda x: x[0])
|
||||
Parses the semester string into a sortable format.
|
||||
Returns a tuple of (year, type), where type is 0 for SoSe and 1 for WiSe.
|
||||
"""
|
||||
if semester.startswith("SoSe"):
|
||||
return int(semester.split()[1]), 0
|
||||
elif semester.startswith("WiSe"):
|
||||
year_part = semester.split()[1]
|
||||
start_year, _ = map(int, year_part.split("/"))
|
||||
return start_year, 1
|
||||
else:
|
||||
raise ValueError(f"Invalid semester format: {semester}")
|
||||
|
||||
# Merge the lists
|
||||
ret = []
|
||||
i = 0
|
||||
j = 0
|
||||
while i < len(summer) and j < len(winter):
|
||||
if summer[i][0][5:] <= winter[j][0][5:]:
|
||||
ret.append(summer[i])
|
||||
i += 1
|
||||
|
||||
def custom_sort(entries):
|
||||
"""
|
||||
Sorts the list of tuples based on the custom schema.
|
||||
|
||||
:param entries: List of tuples in the format (str, int, int).
|
||||
:return: Sorted list of tuples.
|
||||
"""
|
||||
return sorted(
|
||||
entries,
|
||||
key=lambda entry: (
|
||||
parse_semester(entry[0]), # Sort by semester parsed as (year, type)
|
||||
entry[1], # Then by the second element of the tuple
|
||||
entry[2], # Finally by the third element of the tuple
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def parse_semester(semester: str):
|
||||
"""
|
||||
Parses the semester string into a sortable format.
|
||||
Returns a tuple of (year, type), where type is 0 for SoSe and 1 for WiSe.
|
||||
"""
|
||||
if semester.startswith("SoSe"):
|
||||
return int(semester.split()[1]), 0
|
||||
elif semester.startswith("WiSe"):
|
||||
year_part = semester.split()[1]
|
||||
if "/" in year_part:
|
||||
start_year, _ = map(int, year_part.split("/"))
|
||||
else:
|
||||
ret.append(winter[j])
|
||||
j += 1
|
||||
start_year = int(year_part)
|
||||
return start_year, 1
|
||||
else:
|
||||
raise ValueError(f"Invalid semester format: {semester}")
|
||||
|
||||
# Append the remaining items
|
||||
while i < len(summer):
|
||||
ret.append(summer[i])
|
||||
i += 1
|
||||
while j < len(winter):
|
||||
ret.append(winter[j])
|
||||
j += 1
|
||||
|
||||
return ret
|
||||
def sort_semesters_list(semesters: list) -> list:
|
||||
"""
|
||||
Sorts a list of semester strings based on year and type.
|
||||
|
||||
# Test the function
|
||||
|
||||
pass
|
||||
:param semesters: List of semester strings (e.g., "SoSe 24", "WiSe 22/23").
|
||||
:return: Sorted list of semester strings.
|
||||
"""
|
||||
return sorted(semesters, key=parse_semester)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unsorted = [
|
||||
("WiSe 23/24", 7, 5),
|
||||
("SoSe 23", 5, 0),
|
||||
("SoSe 22", 1, 0),
|
||||
("WiSe 22/23", 1, 0),
|
||||
("SoSe 15", 1, 0),
|
||||
"SoSe 24",
|
||||
"WiSe 22/23",
|
||||
"WiSe 23/24",
|
||||
"WiSe 20/21",
|
||||
"SoSe 23",
|
||||
"SoSe 20",
|
||||
"WiSe 7/8",
|
||||
"WiSe 14/15",
|
||||
"WiSe 13/14",
|
||||
"SoSe 8",
|
||||
"WiSe 19/20",
|
||||
"WiSe 12/13",
|
||||
"WiSe 21/22",
|
||||
"WiSe 18/19",
|
||||
"WiSe 11/12",
|
||||
"WiSe 9/10",
|
||||
"WiSe 6/7",
|
||||
"SoSe 7",
|
||||
"WiSe 16/17",
|
||||
"WiSe 24/25",
|
||||
"SoSe 25",
|
||||
]
|
||||
|
||||
# print(custom_sort(unsorted))
|
||||
print(sort_semesters_list(unsorted))
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from enum import Enum
|
||||
|
||||
APP_NRS = [i for i in range(1, 181)]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import csv
|
||||
|
||||
import chardet
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import re
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
@dataclass
|
||||
class Prof:
|
||||
id: int = None
|
||||
_title: str = None
|
||||
firstname: str= None
|
||||
lastname: str= None
|
||||
fullname: str= None
|
||||
mail: str= None
|
||||
telnr: str= None
|
||||
firstname: str = None
|
||||
lastname: str = None
|
||||
fullname: str = None
|
||||
mail: str = None
|
||||
telnr: str = None
|
||||
|
||||
#add function that sets the data based on a dict
|
||||
# add function that sets the data based on a dict
|
||||
def from_dict(self, data: dict):
|
||||
for key, value in data.items():
|
||||
if hasattr(self, key):
|
||||
@@ -28,7 +30,8 @@ class Prof:
|
||||
@title.setter
|
||||
def title(self, value):
|
||||
self._title = value
|
||||
#add function that sets the data from a tuple
|
||||
|
||||
# add function that sets the data from a tuple
|
||||
def from_tuple(self, data: tuple):
|
||||
setattr(self, "id", data[0])
|
||||
setattr(self, "_title", data[1])
|
||||
@@ -40,40 +43,18 @@ class Prof:
|
||||
return self
|
||||
|
||||
def name(self, comma=False):
|
||||
if self.firstname is None and self.lastname is None:
|
||||
if "," in self.fullname:
|
||||
self.firstname = self.fullname.split(",")[1].strip()
|
||||
self.lastname = self.fullname.split(",")[0].strip()
|
||||
else:
|
||||
return self.fullname
|
||||
|
||||
if comma:
|
||||
return f"{self.lastname}, {self.firstname}"
|
||||
return f"{self.lastname} {self.firstname}"
|
||||
|
||||
|
||||
@dataclass
|
||||
class ApparatData:
|
||||
prof_title: str | None = None
|
||||
profname: str | None = None
|
||||
dauerapp: bool = False
|
||||
appnr: int | None = None
|
||||
appname: str | None = None
|
||||
app_fach: str | None = None
|
||||
semester: str | None = None
|
||||
erstellsemester: str | None = None
|
||||
prof_mail: str | None = None
|
||||
prof_tel: int | None = None
|
||||
deleted: int = 0
|
||||
prof_adis_id: int | None = None
|
||||
apparat_adis_id: int | None = None
|
||||
@property
|
||||
def prof_details(self) -> Prof:
|
||||
return Prof().from_dict({
|
||||
"title": self.prof_title,
|
||||
"firstname": self.profname.split(',')[1].strip(),
|
||||
"lastname": self.profname.split(',')[0].strip(),
|
||||
"mail": self.prof_mail,
|
||||
"telnr": self.prof_tel,
|
||||
"fullname": f"{self.profname.split(',')[0].strip()} {self.profname.split(',')[1].strip()}",
|
||||
})
|
||||
def translateToFullname(self):
|
||||
|
||||
return f"{self.profname.split(',')[0].strip()} {self.profname.split(',')[1].strip()}"
|
||||
|
||||
@dataclass
|
||||
class BookData:
|
||||
ppn: str | None = None
|
||||
@@ -132,7 +113,7 @@ class Subjects(Enum):
|
||||
FRENCH = (6, "Französisch")
|
||||
GEOGRAPHY = (7, "Geographie")
|
||||
HISTORY = (8, "Geschichte")
|
||||
HEALT_EDUCATION = (9, "Gesundheitspädagogik")
|
||||
HEALTH_EDUCATION = (9, "Gesundheitspädagogik")
|
||||
HTW = (10, "Haushalt / Textil")
|
||||
ART = (11, "Kunst")
|
||||
MATH_IT = (12, "Mathematik / Informatik")
|
||||
@@ -197,6 +178,13 @@ class Apparat:
|
||||
setattr(self, "konto", data[13])
|
||||
return self
|
||||
|
||||
@property
|
||||
def get_semester(self):
|
||||
if self.extend_until is not None:
|
||||
return self.extend_until
|
||||
else:
|
||||
return self.created_semester
|
||||
|
||||
|
||||
@dataclass
|
||||
class ELSA:
|
||||
@@ -211,3 +199,7 @@ class ELSA:
|
||||
setattr(self, "semester", data[2])
|
||||
setattr(self, "prof_id", data[3])
|
||||
return self
|
||||
@dataclass
|
||||
class ApparatData:
|
||||
prof: Prof = field(default_factory=Prof)
|
||||
apparat: Apparat = field(default_factory=Apparat)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import csv
|
||||
|
||||
import pandas as pd
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
import yaml
|
||||
|
||||
@@ -3,7 +3,7 @@ import sqlite3
|
||||
from PyQt6.QtCore import QThread
|
||||
from PyQt6.QtCore import pyqtSignal as Signal
|
||||
from src.backend.database import Database
|
||||
from src.logic.log import MyLogger
|
||||
|
||||
from src.logic.webrequest import BibTextTransformer, WebRequest
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@ class BookGrabber(QThread):
|
||||
def __init__(self, appnr):
|
||||
super(BookGrabber, self).__init__(parent=None)
|
||||
self.is_Running = True
|
||||
self.logger = MyLogger("Worker")
|
||||
self.logger.log_info("Starting worker thread")
|
||||
logger.info("Starting worker thread")
|
||||
self.data = None
|
||||
self.app_id = None
|
||||
self.prof_id = None
|
||||
@@ -35,9 +34,9 @@ class BookGrabber(QThread):
|
||||
self.data = data
|
||||
self.use_any = any_book
|
||||
self.use_exact = exact
|
||||
self.logger.log_info(f"Working on {len(self.data)} entries")
|
||||
logger.info(f"Working on {len(self.data)} entries")
|
||||
self.tstate = (self.app_id, self.prof_id, self.mode, self.data)
|
||||
self.logger.log_debug("State: " + str(self.tstate))
|
||||
logger.debug("State: " + str(self.tstate))
|
||||
# print(self.tstate)
|
||||
|
||||
def run(self):
|
||||
@@ -50,7 +49,7 @@ class BookGrabber(QThread):
|
||||
for entry in iterdata:
|
||||
# print(entry)
|
||||
signature = str(entry)
|
||||
self.logger.log_info("Processing entry: " + signature)
|
||||
logger.info("Processing entry: " + signature)
|
||||
|
||||
webdata = WebRequest().set_apparat(self.appnr).get_ppn(entry)
|
||||
if self.use_any:
|
||||
@@ -79,7 +78,7 @@ class BookGrabber(QThread):
|
||||
self.db.addBookToDatabase(bd, self.app_id, self.prof_id)
|
||||
# get latest book id
|
||||
self.book_id = self.db.getLastBookId()
|
||||
self.logger.log_info("Added book to database")
|
||||
logger.info("Added book to database")
|
||||
state = 0
|
||||
for result in transformer.RDS_DATA:
|
||||
# print(result.RDS_LOCATION)
|
||||
@@ -87,17 +86,17 @@ class BookGrabber(QThread):
|
||||
state = 1
|
||||
break
|
||||
|
||||
self.logger.log_info(f"State of {signature}: {state}")
|
||||
logger.info(f"State of {signature}: {state}")
|
||||
# print("updating availability of " + str(self.book_id) + " to " + str(state))
|
||||
try:
|
||||
self.db.setAvailability(self.book_id, state)
|
||||
except sqlite3.OperationalError as e:
|
||||
self.logger.log_error(f"Failed to update availability: {e}")
|
||||
logger.error(f"Failed to update availability: {e}")
|
||||
|
||||
# time.sleep(5)
|
||||
item += 1
|
||||
self.updateSignal.emit(item, len(self.data))
|
||||
self.logger.log_info("Worker thread finished")
|
||||
logger.info("Worker thread finished")
|
||||
# self.done.emit()
|
||||
self.quit()
|
||||
|
||||
@@ -111,17 +110,17 @@ class BookGrabber(QThread):
|
||||
# def __init__(self, app_id, prof_id, mode, data, parent=None):
|
||||
# super(BookGrabber, self).__init__(parent=None)
|
||||
# self.is_Running = True
|
||||
# self.logger = MyLogger("Worker")
|
||||
# self.logger.log_info("Starting worker thread")
|
||||
# logger = MyLogger("Worker")
|
||||
# logger.info("Starting worker thread")
|
||||
# self.data = data
|
||||
# self.logger.log_info(f"Working on {len(self.data)} entries")
|
||||
# logger.info(f"Working on {len(self.data)} entries")
|
||||
# self.app_id = app_id
|
||||
# self.prof_id = prof_id
|
||||
# self.mode = mode
|
||||
# self.book_id = None
|
||||
# self.state = (self.app_id, self.prof_id, self.mode, self.data)
|
||||
# # print(self.state)
|
||||
# self.logger.log_info("state: " + str(self.state))
|
||||
# logger.info("state: " + str(self.state))
|
||||
# # time.sleep(2)
|
||||
|
||||
# def resetValues(self):
|
||||
@@ -140,7 +139,7 @@ class BookGrabber(QThread):
|
||||
# for entry in iterdata:
|
||||
# # print(entry)
|
||||
# signature = str(entry)
|
||||
# self.logger.log_info("Processing entry: " + signature)
|
||||
# logger.info("Processing entry: " + signature)
|
||||
|
||||
# webdata = WebRequest().get_ppn(entry).get_data()
|
||||
# if webdata == "error":
|
||||
@@ -153,19 +152,19 @@ class BookGrabber(QThread):
|
||||
# self.db.addBookToDatabase(bd, self.app_id, self.prof_id)
|
||||
# # get latest book id
|
||||
# self.book_id = self.db.getLastBookId()
|
||||
# self.logger.log_info("Added book to database")
|
||||
# logger.info("Added book to database")
|
||||
# state = 0
|
||||
# # print(len(rds.items))
|
||||
# for rds_item in rds.items:
|
||||
# sign = rds_item.superlocation
|
||||
# loc = rds_item.location
|
||||
# # ic(sign, loc)
|
||||
# # ic(rds_item)
|
||||
# # logger.debug(sign, loc)
|
||||
# # logger.debug(rds_item)
|
||||
# if self.app_id in sign or self.app_id in loc:
|
||||
# state = 1
|
||||
# break
|
||||
|
||||
# self.logger.log_info(f"State of {signature}: {state}")
|
||||
# logger.info(f"State of {signature}: {state}")
|
||||
# # print(
|
||||
# "updating availability of "
|
||||
# + str(self.book_id)
|
||||
@@ -175,12 +174,12 @@ class BookGrabber(QThread):
|
||||
# try:
|
||||
# self.db.setAvailability(self.book_id, state)
|
||||
# except sqlite3.OperationalError as e:
|
||||
# self.logger.log_error(f"Failed to update availability: {e}")
|
||||
# logger.error(f"Failed to update availability: {e}")
|
||||
|
||||
# # time.sleep(5)
|
||||
# item += 1
|
||||
# self.updateSignal.emit(item, len(self.data))
|
||||
# self.logger.log_info("Worker thread finished")
|
||||
# logger.info("Worker thread finished")
|
||||
# # self.done.emit()
|
||||
# self.stop()
|
||||
# if not self.is_Running:
|
||||
|
||||
@@ -5,7 +5,7 @@ from PyQt6.QtCore import QThread
|
||||
from PyQt6.QtCore import pyqtSignal as Signal
|
||||
|
||||
from src.backend.database import Database
|
||||
from src.logic.log import MyLogger
|
||||
|
||||
|
||||
# from src.transformers import RDS_AVAIL_DATA
|
||||
|
||||
@@ -18,7 +18,6 @@ class AutoAdder(QThread):
|
||||
|
||||
def __init__(self, data=None, app_id=None, prof_id=None, parent=None):
|
||||
super().__init__(parent)
|
||||
self.logger = MyLogger("AutoAdder")
|
||||
self.data = data
|
||||
self.app_id = app_id
|
||||
self.prof_id = prof_id
|
||||
@@ -29,7 +28,7 @@ class AutoAdder(QThread):
|
||||
def run(self):
|
||||
self.db = Database()
|
||||
# show the dialog, start the thread to gather data and dynamically update progressbar and listwidget
|
||||
self.logger.log_info("Starting worker thread")
|
||||
logger.info("Starting worker thread")
|
||||
item = 0
|
||||
for entry in self.data:
|
||||
try:
|
||||
@@ -42,11 +41,11 @@ class AutoAdder(QThread):
|
||||
|
||||
except Exception as e:
|
||||
# print(e)
|
||||
self.logger.log_exception(
|
||||
logger.exception(
|
||||
f"The query failed with message {e} for signature {entry}"
|
||||
)
|
||||
continue
|
||||
if item == len(self.data):
|
||||
self.logger.log_info("Worker thread finished")
|
||||
logger.info("Worker thread finished")
|
||||
# teminate thread
|
||||
self.finished.emit()
|
||||
|
||||
@@ -5,7 +5,7 @@ from PyQt6.QtCore import QThread
|
||||
from PyQt6.QtCore import pyqtSignal as Signal
|
||||
|
||||
from src.backend.database import Database
|
||||
from src.logic.log import MyLogger
|
||||
|
||||
from src.logic.webrequest import BibTextTransformer, WebRequest
|
||||
|
||||
# from src.transformers import RDS_AVAIL_DATA
|
||||
@@ -21,9 +21,8 @@ class AvailChecker(QThread):
|
||||
if links is None:
|
||||
links = []
|
||||
super().__init__(parent)
|
||||
self.logger = MyLogger("AvailChecker")
|
||||
self.logger.log_info("Starting worker thread")
|
||||
self.logger.log_info(
|
||||
logger.info("Starting worker thread")
|
||||
logger.info(
|
||||
"Checking availability for "
|
||||
+ str(links)
|
||||
+ " with appnumber "
|
||||
@@ -33,7 +32,7 @@ class AvailChecker(QThread):
|
||||
self.links = links
|
||||
self.appnumber = appnumber
|
||||
self.books = books
|
||||
self.logger.log_info(
|
||||
logger.info(
|
||||
f"Started worker with appnumber: {self.appnumber} and links: {self.links} and {len(self.books)} books..."
|
||||
)
|
||||
time.sleep(2)
|
||||
@@ -43,7 +42,7 @@ class AvailChecker(QThread):
|
||||
state = 0
|
||||
count = 0
|
||||
for link in self.links:
|
||||
self.logger.log_info("Processing entry: " + str(link))
|
||||
logger.info("Processing entry: " + str(link))
|
||||
data = WebRequest().set_apparat(self.appnumber).get_ppn(link).get_data()
|
||||
transformer = BibTextTransformer("RDS")
|
||||
rds = transformer.get_data(data).return_data("rds_availability")
|
||||
@@ -60,14 +59,14 @@ class AvailChecker(QThread):
|
||||
if book["bookdata"].signature == link:
|
||||
book_id = book["id"]
|
||||
break
|
||||
self.logger.log_info(f"State of {link}: " + str(state))
|
||||
logger.info(f"State of {link}: " + str(state))
|
||||
# print("Updating availability of " + str(book_id) + " to " + str(state))
|
||||
self.db.setAvailability(book_id, state)
|
||||
count += 1
|
||||
self.updateProgress.emit(count, len(self.links))
|
||||
self.updateSignal.emit(item.callnumber, state)
|
||||
|
||||
self.logger.log_info("Worker thread finished")
|
||||
logger.info("Worker thread finished")
|
||||
# teminate thread
|
||||
|
||||
self.quit()
|
||||
|
||||
@@ -5,10 +5,9 @@ from bs4 import BeautifulSoup
|
||||
from ratelimit import limits, sleep_and_retry
|
||||
|
||||
from src.logic.dataclass import BookData
|
||||
from src.logic.log import MyLogger
|
||||
|
||||
from src.transformers import ARRAYData, BibTeXData, COinSData, RDSData, RISData
|
||||
|
||||
logger = MyLogger(__name__)
|
||||
|
||||
API_URL = "https://rds.ibs-bw.de/phfreiburg/opac/RDSIndexrecord/{}/"
|
||||
PPN_URL = "https://rds.ibs-bw.de/phfreiburg/opac/RDSIndex/Search?type0%5B%5D=allfields&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=au&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=ti&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=ct&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=isn&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=ta&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=co&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=py&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=pp&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=pu&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=si&lookfor0%5B%5D={}&join=AND&bool0%5B%5D=AND&type0%5B%5D=zr&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND&type0%5B%5D=cc&lookfor0%5B%5D=&join=AND&bool0%5B%5D=AND"
|
||||
@@ -37,19 +36,19 @@ class WebRequest:
|
||||
self.ppn = None
|
||||
self.data = None
|
||||
self.timeout = 5
|
||||
logger.log_info("Initialized WebRequest")
|
||||
logger.info("Initialized WebRequest")
|
||||
|
||||
@property
|
||||
def use_any_book(self):
|
||||
"""use any book that matches the search term"""
|
||||
self.use_any = True
|
||||
logger.log_info("Using any book")
|
||||
logger.info("Using any book")
|
||||
return self
|
||||
def set_apparat(self, apparat):
|
||||
self.apparat = apparat
|
||||
if int(self.apparat) < 10:
|
||||
self.apparat = f"0{self.apparat}"
|
||||
logger.log_info(f"Set apparat to {self.apparat}")
|
||||
logger.info(f"Set apparat to {self.apparat}")
|
||||
return self
|
||||
|
||||
def get_ppn(self, signature):
|
||||
@@ -81,7 +80,7 @@ class WebRequest:
|
||||
response = requests.get(link, timeout=self.timeout)
|
||||
return response.text
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.log_error(f"Request failed: {e}")
|
||||
logger.error(f"Request failed: {e}")
|
||||
return None
|
||||
def get_data(self):
|
||||
links = self.get_book_links(self.ppn)
|
||||
@@ -105,7 +104,7 @@ class WebRequest:
|
||||
return_data.append(data)
|
||||
return return_data
|
||||
else:
|
||||
logger.log_error("No <pre> tag found")
|
||||
logger.error("No <pre> tag found")
|
||||
raise ValueError("No <pre> tag found")
|
||||
if f"Semesterapparat-{self.apparat}" in item_location:
|
||||
pre_tag = soup.find_all("pre")
|
||||
@@ -116,7 +115,7 @@ class WebRequest:
|
||||
return_data.append(data)
|
||||
return return_data
|
||||
else:
|
||||
logger.log_error("No <pre> tag found")
|
||||
logger.error("No <pre> tag found")
|
||||
return return_data
|
||||
|
||||
def get_data_elsa(self):
|
||||
@@ -137,7 +136,7 @@ class WebRequest:
|
||||
return_data.append(data)
|
||||
return return_data
|
||||
else:
|
||||
logger.log_error("No <pre> tag found")
|
||||
logger.error("No <pre> tag found")
|
||||
return return_data
|
||||
|
||||
|
||||
@@ -155,7 +154,7 @@ class BibTextTransformer:
|
||||
self.field = None
|
||||
self.signature = None
|
||||
if mode not in self.valid_modes:
|
||||
logger.log_error(f"Mode {mode} not valid")
|
||||
logger.error(f"Mode {mode} not valid")
|
||||
raise ValueError(f"Mode {mode} not valid")
|
||||
self.data = None
|
||||
# self.bookdata = BookData(**self.data)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import pandas as pd
|
||||
from docx import Document
|
||||
import re
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from pyzotero import zotero
|
||||
from dataclasses import dataclass
|
||||
from src.logic.webrequest import WebRequest, BibTextTransformer
|
||||
|
||||
122
src/transformers/schemas.py
Normal file
122
src/transformers/schemas.py
Normal file
@@ -0,0 +1,122 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional, Any, List
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import field as dataclass_field
|
||||
import json
|
||||
|
||||
|
||||
@dataclass
|
||||
class Item:
|
||||
superlocation: str | None = dataclass_field(default_factory=str)
|
||||
status: str | None = dataclass_field(default_factory=str)
|
||||
availability: str | None = dataclass_field(default_factory=str)
|
||||
notes: str | None = dataclass_field(default_factory=str)
|
||||
limitation: str | None = dataclass_field(default_factory=str)
|
||||
duedate: str | None = dataclass_field(default_factory=str)
|
||||
id: str | None = dataclass_field(default_factory=str)
|
||||
item_id: str | None = dataclass_field(default_factory=str)
|
||||
ilslink: str | None = dataclass_field(default_factory=str)
|
||||
number: int | None = dataclass_field(default_factory=int)
|
||||
barcode: str | None = dataclass_field(default_factory=str)
|
||||
reserve: str | None = dataclass_field(default_factory=str)
|
||||
callnumber: str | None = dataclass_field(default_factory=str)
|
||||
department: str | None = dataclass_field(default_factory=str)
|
||||
locationhref: str | None = dataclass_field(default_factory=str)
|
||||
location: str | None = dataclass_field(default_factory=str)
|
||||
|
||||
def from_dict(self, data: dict):
|
||||
"""Import data from dict"""
|
||||
data = data["items"]
|
||||
for entry in data:
|
||||
for key, value in entry.items():
|
||||
setattr(self, key, value)
|
||||
return self
|
||||
|
||||
|
||||
@dataclass
|
||||
class RDS_AVAIL_DATA:
|
||||
"""Class to store RDS availability data"""
|
||||
|
||||
library_sigil: str = dataclass_field(default_factory=str)
|
||||
items: List[Item] = dataclass_field(default_factory=list)
|
||||
|
||||
def import_from_dict(self, data: str):
|
||||
"""Import data from dict"""
|
||||
edata = json.loads(data)
|
||||
# library sigil is first key
|
||||
|
||||
self.library_sigil = str(list(edata.keys())[0])
|
||||
# get data from first key
|
||||
edata = edata[self.library_sigil]
|
||||
for location in edata:
|
||||
item = Item(superlocation=location).from_dict(edata[location])
|
||||
|
||||
self.items.append(item)
|
||||
return self
|
||||
|
||||
|
||||
@dataclass
|
||||
class RDS_DATA:
|
||||
"""Class to store RDS data"""
|
||||
|
||||
RDS_SIGNATURE: str = dataclass_field(default_factory=str)
|
||||
RDS_STATUS: str = dataclass_field(default_factory=str)
|
||||
RDS_LOCATION: str = dataclass_field(default_factory=str)
|
||||
RDS_URL: Any = dataclass_field(default_factory=str)
|
||||
RDS_HINT: Any = dataclass_field(default_factory=str)
|
||||
RDS_COMMENT: Any = dataclass_field(default_factory=str)
|
||||
RDS_HOLDING: Any = dataclass_field(default_factory=str)
|
||||
RDS_HOLDING_LEAK: Any = dataclass_field(default_factory=str)
|
||||
RDS_INTERN: Any = dataclass_field(default_factory=str)
|
||||
RDS_PROVENIENCE: Any = dataclass_field(default_factory=str)
|
||||
RDS_LOCAL_NOTATION: str = dataclass_field(default_factory=str)
|
||||
RDS_LEA: Any = dataclass_field(default_factory=str)
|
||||
|
||||
def import_from_dict(self, data: dict) -> RDS_DATA:
|
||||
"""Import data from dict"""
|
||||
for key, value in data.items():
|
||||
setattr(self, key, value)
|
||||
return self
|
||||
|
||||
|
||||
@dataclass
|
||||
class RDS_GENERIC_DATA:
|
||||
LibrarySigil: str = dataclass_field(default_factory=str)
|
||||
RDS_DATA: List[RDS_DATA] = dataclass_field(default_factory=list)
|
||||
|
||||
def import_from_dict(self, data: str) -> RDS_GENERIC_DATA:
|
||||
"""Import data from dict"""
|
||||
edata = json.loads(data)
|
||||
# library sigil is first key
|
||||
self.LibrarySigil = str(list(edata.keys())[0])
|
||||
# get data from first key
|
||||
edata = edata[self.LibrarySigil]
|
||||
for entry in edata:
|
||||
rds_data = RDS_DATA() # Create a new RDS_DATA instance
|
||||
# Populate the RDS_DATA instance from the entry
|
||||
# This assumes that the entry is a dictionary that matches the structure of the RDS_DATA class
|
||||
rds_data.import_from_dict(entry)
|
||||
self.RDS_DATA.append(rds_data) # Add the RDS_DATA instance to the list
|
||||
return self
|
||||
|
||||
|
||||
@dataclass
|
||||
class LoksatzData:
|
||||
type: Optional[str] = None
|
||||
adis_idn: Optional[str] = None
|
||||
t_idn: Optional[str] = None
|
||||
ktrl_nr: Optional[str] = None
|
||||
adis_isil: Optional[str] = None
|
||||
adis_sigel: Optional[str] = None
|
||||
bib_sigel: Optional[str] = None
|
||||
standort: Optional[str] = None
|
||||
signatur: Optional[str] = None
|
||||
ausleihcode: Optional[str] = None
|
||||
sig_katalog: Optional[str] = None
|
||||
erwerb_datum: Optional[str] = None
|
||||
medientypcode: Optional[str] = None
|
||||
bestellart: Optional[str] = None
|
||||
faecherstatistik: Optional[str] = None
|
||||
exemplar_stat: Optional[str] = None
|
||||
so_standort: Optional[str] = None
|
||||
@@ -8,10 +8,8 @@ from typing import Any, List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from src.logic.dataclass import BookData
|
||||
from src.logic.log import MyLogger
|
||||
|
||||
logger = MyLogger("transformers.py")
|
||||
from src.logic.dataclass import BookData
|
||||
|
||||
|
||||
###Pydatnic models
|
||||
@@ -135,7 +133,7 @@ class ARRAYData:
|
||||
|
||||
except Exception:
|
||||
# # print(f"ARRAYData.transform failed, {source}, {search}")
|
||||
logger.log_exception(f"ARRAYData.transform failed, no string {search}")
|
||||
logger.exception(f"ARRAYData.transform failed, no string {search}")
|
||||
return ""
|
||||
|
||||
def _get_list_entry(source: str, search: str, entry: str) -> str:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import pathlib
|
||||
|
||||
from .Ui_semesterapparat_ui import Ui_MainWindow as Ui_Semesterapparat
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from .bookdata import BookDataUI as edit_bookdata_ui
|
||||
from .login import LoginDialog as login_ui
|
||||
from .mail import Mail_Dialog
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from .dialog_sources.Ui_about import Ui_about
|
||||
from PyQt6 import QtWidgets
|
||||
from PyQt6.QtCore import PYQT_VERSION_STR
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
from PyQt6 import QtWidgets
|
||||
from .dialog_sources.Ui_apparat_extend import Ui_Dialog
|
||||
from src import Icon
|
||||
from src.backend import generateSemesterByDate, generateSemesterByOffset
|
||||
from src.backend import Semester
|
||||
class ApparatExtendDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from PyQt6 import QtCore, QtWidgets
|
||||
|
||||
from src.logic.dataclass import BookData
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from .dialog_sources.Ui_confirm_extend import Ui_extend_confirm
|
||||
from PyQt6 import QtWidgets
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\about.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.6.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\app_status.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.6.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\apparat_extend.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\confirm_extend.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\edit_bookdata.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.6.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\elsa_add_table_entry.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\elsa_generate_citation.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.6.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\elsa_generator_confirm.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.6.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\login.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.6.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\mail_preview.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\medianadder.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\newMailTemplateDesigner.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.6.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\parsed_titles.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.6.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\reminder.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.6.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\dialog_sources\settings.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
from .dialog_sources.Ui_elsa_add_table_entry import Ui_Dialog
|
||||
from src.logic.webrequest import WebRequest, BibTextTransformer
|
||||
from src import Icon
|
||||
from PyQt6 import QtWidgets
|
||||
from src.transformers.transformers import DictToTable
|
||||
from src.logic.zotero import ZoteroController
|
||||
from icecream import ic
|
||||
|
||||
zot = ZoteroController()
|
||||
dtt = DictToTable()
|
||||
@@ -117,7 +117,7 @@ class ElsaAddEntry(QtWidgets.QDialog, Ui_Dialog):
|
||||
if table["type"] == "zs":
|
||||
book = zot.createBook(table["isbn"])
|
||||
res_key = zot.createJournalArticle(book, table)
|
||||
ic(book)
|
||||
logger.debug(book)
|
||||
a_lastname = table["section_author"].split(";")[0].strip().split(",")[0]
|
||||
a_firstname = table["section_author"].split(";")[0].strip().split(",")[1]
|
||||
author = f"{a_lastname}, {a_firstname[0]}"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from .dialog_sources.Ui_elsa_generate_citation import Ui_Dialog
|
||||
from PyQt6 import QtWidgets
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from .dialog_sources.Ui_elsa_generator_confirm import Ui_Dialog
|
||||
from PyQt6 import QtCore, QtWidgets, QtGui
|
||||
|
||||
|
||||
@@ -2,16 +2,15 @@ import hashlib
|
||||
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from src import Icon
|
||||
from src import Icon, logger
|
||||
from src.backend.admin_console import AdminCommands
|
||||
from src.backend.database import Database
|
||||
|
||||
from .dialog_sources.Ui_login import Ui_Dialog
|
||||
from src import MyLogger
|
||||
|
||||
|
||||
class LoginDialog(Ui_Dialog):
|
||||
def setupUi(self, Dialog):
|
||||
self.log = MyLogger("Login")
|
||||
Dialog.setObjectName("Dialog")
|
||||
Dialog.resize(218, 190)
|
||||
self.dialog = Dialog
|
||||
@@ -76,16 +75,20 @@ class LoginDialog(Ui_Dialog):
|
||||
if self.db.login(username, hashed_password):
|
||||
self.lresult = 1 # Indicate successful login
|
||||
self.lusername = username
|
||||
logger.success(f"User {username} logged in.")
|
||||
self.dialog.accept()
|
||||
|
||||
else:
|
||||
# Credentials are invalid, display a warning
|
||||
if username == "" or password == "":
|
||||
logger.warning("Invalid username or password. Login failed.")
|
||||
warning_dialog = QtWidgets.QMessageBox()
|
||||
warning_dialog.setIcon(QtWidgets.QMessageBox.Icon.Warning)
|
||||
warning_dialog.setText("Please enter a username and password.")
|
||||
warning_dialog.setWindowTitle("Login Failed")
|
||||
warning_dialog.exec()
|
||||
else:
|
||||
logger.warning("Invalid username or password. Login failed.")
|
||||
warning_dialog = QtWidgets.QMessageBox()
|
||||
warning_dialog.setIcon(QtWidgets.QMessageBox.Icon.Warning)
|
||||
warning_dialog.setText(
|
||||
|
||||
@@ -4,14 +4,12 @@ import sys
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from src import Icon, settings as config
|
||||
from src.logic.log import MyLogger
|
||||
|
||||
|
||||
from .dialog_sources.Ui_mail_preview import Ui_eMailPreview as MailPreviewDialog
|
||||
from .mailTemplate import MailTemplateDialog
|
||||
|
||||
|
||||
logger = MyLogger("Mail")
|
||||
|
||||
empty_signature = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
|
||||
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style
|
||||
@@ -52,7 +50,7 @@ class Mail_Dialog(QtWidgets.QDialog, MailPreviewDialog):
|
||||
# prof_name,
|
||||
)
|
||||
|
||||
logger.log_info("Setting up mail dialog")
|
||||
logger.info("Setting up mail dialog")
|
||||
self.appid = app_id
|
||||
self.appname = app_name
|
||||
self.subject = app_subject
|
||||
@@ -84,7 +82,7 @@ class Mail_Dialog(QtWidgets.QDialog, MailPreviewDialog):
|
||||
self.btn_okay.clicked.connect(self.createAndSendMail)
|
||||
|
||||
def open_new_template(self):
|
||||
logger.log_info("Opening new template dialog")
|
||||
logger.info("Opening new template dialog")
|
||||
# TODO: implement new mail template dialog
|
||||
dialog = MailTemplateDialog()
|
||||
dialog.exec()
|
||||
@@ -101,9 +99,9 @@ Tel.: 0761/682-778 | 07617682-545"""
|
||||
|
||||
def load_mail_templates(self):
|
||||
# print("loading mail templates")
|
||||
logger.log_info("Loading mail templates")
|
||||
logger.info("Loading mail templates")
|
||||
mail_templates = os.listdir("mail_vorlagen")
|
||||
logger.log_info(f"Mail templates: {mail_templates}")
|
||||
logger.info(f"Mail templates: {mail_templates}")
|
||||
for template in mail_templates:
|
||||
self.comboBox.addItem(template)
|
||||
|
||||
@@ -121,10 +119,10 @@ Tel.: 0761/682-778 | 07617682-545"""
|
||||
return f"Guten Tag {name},"
|
||||
|
||||
def set_mail(self):
|
||||
logger.log_info("Setting mail")
|
||||
logger.info("Setting mail")
|
||||
email_template = self.comboBox.currentText()
|
||||
if email_template == "":
|
||||
logger.log_debug("No mail template selected")
|
||||
logger.debug("No mail template selected")
|
||||
return
|
||||
with open(f"mail_vorlagen/{email_template}", "r", encoding="utf-8") as f:
|
||||
mail_template = f.read()
|
||||
@@ -147,10 +145,10 @@ Tel.: 0761/682-778 | 07617682-545"""
|
||||
)
|
||||
|
||||
self.mail_body.setHtml(mail_html)
|
||||
logger.log_info(f"Mail template set to {email_template}")
|
||||
logger.info(f"Mail template set to {email_template}")
|
||||
|
||||
def createAndSendMail(self):
|
||||
logger.log_info("Sending mail")
|
||||
logger.info("Sending mail")
|
||||
import smtplib
|
||||
import ssl
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
@@ -188,7 +186,7 @@ Tel.: 0761/682-778 | 07617682-545"""
|
||||
# print("Mail sent")
|
||||
# end active process
|
||||
server.quit()
|
||||
logger.log_info("Mail sent, closing connection to server and dialog")
|
||||
logger.info("Mail sent, closing connection to server and dialog")
|
||||
# close the dialog
|
||||
|
||||
self.accept()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import os
|
||||
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'ui\dialogs\mail_preview.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.3.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
from src import MyLogger
|
||||
|
||||
from .dialog_sources.Ui_medianadder import Ui_Dialog
|
||||
from src import Icon
|
||||
class MedienAdder(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file '/home/alexander/GitHub/Semesterapparate/ui/dialogs/new_subject.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.5.3
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
from PyQt6 import QtCore, QtWidgets
|
||||
|
||||
from src.logic import AutoAdder
|
||||
from src.logic.log import MyLogger
|
||||
|
||||
|
||||
from .dialog_sources.Ui_parsed_titles import Ui_Form
|
||||
|
||||
logger = MyLogger("AutoTitleAdder")
|
||||
|
||||
|
||||
class ParsedTitles(QtWidgets.QWidget, Ui_Form):
|
||||
def __init__(self, parent=None):
|
||||
@@ -35,7 +33,7 @@ class ParsedTitles(QtWidgets.QWidget, Ui_Form):
|
||||
self.worker = None
|
||||
|
||||
def start(self):
|
||||
logger.log_info("Starting AutoAdder")
|
||||
logger.info("Starting AutoAdder")
|
||||
|
||||
self.worker = AutoAdder(
|
||||
data=self.signatures,
|
||||
@@ -54,8 +52,8 @@ class ParsedTitles(QtWidgets.QWidget, Ui_Form):
|
||||
self.worker.start()
|
||||
|
||||
def on_completion(self):
|
||||
logger.log_info("AutoAdder finished")
|
||||
logger.log_info("Returning data")
|
||||
logger.info("AutoAdder finished")
|
||||
logger.info("Returning data")
|
||||
|
||||
# create a function that closes the dialog
|
||||
|
||||
@@ -64,7 +62,7 @@ class ParsedTitles(QtWidgets.QWidget, Ui_Form):
|
||||
length = self.listWidget.count()
|
||||
# print(f"Length of listWidget: {length}")
|
||||
if length == 0:
|
||||
logger.log_info("AutoAdder finished")
|
||||
logger.info("AutoAdder finished")
|
||||
self.buttonBox.accepted.emit()
|
||||
|
||||
def update_lists(self, signal):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file '/home/alexander/GitHub/Semesterapparate/ui/dialogs/parsed_titles.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.5.3
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'ui\dialogs\confirm_extend.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.3.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from PyQt6 import QtWidgets
|
||||
|
||||
from .dialog_sources.Ui_reminder import Ui_Erinnerung as Ui_Dialog
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
from src import Icon, settings
|
||||
from .dialog_sources.Ui_settings import Ui_Dialog as _settings
|
||||
|
||||
@@ -7,16 +7,15 @@ import tempfile
|
||||
import webbrowser
|
||||
from pathlib import Path
|
||||
|
||||
from icecream import ic
|
||||
from natsort import natsorted
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
from PyQt6.QtCore import QThread
|
||||
from PyQt6.QtGui import QRegularExpressionValidator
|
||||
|
||||
from src import Icon, settings
|
||||
from src import Icon, settings, logger
|
||||
from src.backend import (
|
||||
Database,
|
||||
generateSemesterByDate,
|
||||
Semester,
|
||||
recreateFile,
|
||||
tempdelete,
|
||||
)
|
||||
@@ -27,9 +26,10 @@ from src.logic import (
|
||||
AvailChecker,
|
||||
BookData,
|
||||
BookGrabber,
|
||||
MyLogger,
|
||||
csv_to_list,
|
||||
word_docx_to_csv,
|
||||
Prof,
|
||||
Apparat,
|
||||
)
|
||||
from src.ui import (
|
||||
About,
|
||||
@@ -50,7 +50,7 @@ from src.ui import (
|
||||
ElsaDialog,
|
||||
UserCreate,
|
||||
EditUser,
|
||||
EditProf
|
||||
EditProf,
|
||||
)
|
||||
from src.utils import SemesterDocument
|
||||
|
||||
@@ -60,8 +60,7 @@ valid_input = (0, 0, 0, 0, 0, 0)
|
||||
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")
|
||||
logger.info("Starting Semesterapparatsmanagement")
|
||||
super().__init__()
|
||||
self.active_user = username
|
||||
self.setupUi(MainWindow)
|
||||
@@ -172,7 +171,6 @@ class Ui(Ui_Semesterapparat):
|
||||
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()
|
||||
@@ -247,7 +245,7 @@ class Ui(Ui_Semesterapparat):
|
||||
apps.append(data)
|
||||
print(apps)
|
||||
doc = SemesterDocument(
|
||||
semester=self.generateSemester(today=True),
|
||||
semester=Semester(),
|
||||
filename="Semesterapparate",
|
||||
apparats=apps,
|
||||
)
|
||||
@@ -372,14 +370,12 @@ class Ui(Ui_Semesterapparat):
|
||||
"""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()
|
||||
return Semester()
|
||||
currentYear = self.sem_year.text()
|
||||
currentYear = int(currentYear[-2:])
|
||||
|
||||
@@ -387,7 +383,7 @@ class Ui(Ui_Semesterapparat):
|
||||
if semester == "SoSe":
|
||||
return "SoSe " + str(currentYear)
|
||||
else:
|
||||
return f"WiSe {currentYear}/{currentYear+1}"
|
||||
return f"WiSe {currentYear}/{currentYear + 1}"
|
||||
|
||||
def open_apparat(self, apparat):
|
||||
if self.load_app_data(apparat):
|
||||
@@ -402,41 +398,29 @@ class Ui(Ui_Semesterapparat):
|
||||
|
||||
def populate_frame(self, appdata: ApparatData):
|
||||
# populate the frame with the data from the database
|
||||
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_app_nr.setCurrentText(str(appdata.apparat.appnr))
|
||||
self.prof_title.setText(appdata.prof.title)
|
||||
prof_name = appdata.prof.name(True)
|
||||
|
||||
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)
|
||||
self.prof_mail.setText(appdata.prof.mail)
|
||||
self.prof_tel_nr.setText(appdata.prof.telnr)
|
||||
self.app_name.setText(appdata.apparat.name)
|
||||
# print("changing dropdown app_fach from '' to ", appdata.app_fach)
|
||||
self.app_fach.setCurrentText(appdata.app_fach)
|
||||
self.app_fach.setCurrentText(appdata.apparat.subject)
|
||||
# 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.sem_year.setText(appdata.apparat.get_semester.split(" ")[1])
|
||||
match appdata.apparat.get_semester.split(" ")[0]:
|
||||
case "SoSe":
|
||||
self.sem_sommer.setChecked(True)
|
||||
self.sem_winter.setChecked(False)
|
||||
case "WiSe":
|
||||
self.sem_sommer.setChecked(False)
|
||||
self.sem_winter.setChecked(True)
|
||||
|
||||
self.check_eternal_app.setChecked(appdata.apparat.eternal)
|
||||
self.prof_id_adis.setText(str(appdata.apparat.prof_id_adis))
|
||||
self.apparat_id_adis.setText(str(appdata.apparat.apparat_id_adis))
|
||||
self.app_group_box.setEnabled(True)
|
||||
self.validateLoadedData()
|
||||
|
||||
@@ -449,25 +433,26 @@ class Ui(Ui_Semesterapparat):
|
||||
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 = (
|
||||
prof = Prof()
|
||||
app = Apparat()
|
||||
app.subject = self.app_fach.currentText()
|
||||
app.name = self.app_name.text()
|
||||
app.appnr = self.active_apparat
|
||||
app.eternal = self.check_eternal_app.isChecked()
|
||||
prof.mail = self.prof_mail.text()
|
||||
prof.telnr = self.prof_tel_nr.text()
|
||||
prof.title = self.prof_title.text()
|
||||
prof.fullname = self.drpdwn_prof_name.currentText().replace(",", "")
|
||||
app.created_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()
|
||||
prof_id = self.db.getProfByName(appdata.prof_details.fullname).id
|
||||
app.prof_id_adis = self.prof_id_adis.text()
|
||||
prof_id = self.db.getProfByName(prof.fullname).id
|
||||
self.add_files(prof_id)
|
||||
appdata.apparat_adis_id = self.apparat_id_adis.text()
|
||||
|
||||
app.apparat_id_adis = self.apparat_id_adis.text()
|
||||
appdata = ApparatData(prof=prof, apparat=app)
|
||||
self.db.updateApparat(appdata)
|
||||
|
||||
self.update_app_media_list()
|
||||
@@ -597,7 +582,7 @@ class Ui(Ui_Semesterapparat):
|
||||
return
|
||||
selected_prof = self.drpdwn_prof_name.currentText()
|
||||
data = self.db.getProfData(selected_prof)
|
||||
# ic(data)
|
||||
# logger.debug(data)
|
||||
prof_title = data.title
|
||||
if prof_title == "None":
|
||||
prof_title = "Kein Titel"
|
||||
@@ -701,13 +686,13 @@ class Ui(Ui_Semesterapparat):
|
||||
|
||||
def update_progress_label(self, curr, total):
|
||||
text = f"Medium {curr}/{total}"
|
||||
self.logger.log_info(text)
|
||||
logger.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")
|
||||
logger.info("Finished adding media, hiding progress label")
|
||||
self.progress_label.hide()
|
||||
self.progress_label.setText("Bitte warten...")
|
||||
self.line_2.hide()
|
||||
@@ -734,7 +719,7 @@ class Ui(Ui_Semesterapparat):
|
||||
|
||||
app_id = self.active_apparat
|
||||
prof_id = self.db.getProfId(self.profdata)
|
||||
ic(prof_id)
|
||||
logger.debug(prof_id)
|
||||
# check if app_id is in database
|
||||
if self.db.checkApparatExistsById(app_id) is False:
|
||||
# create apparat
|
||||
@@ -1066,7 +1051,7 @@ class Ui(Ui_Semesterapparat):
|
||||
data = __open_dialog(signatures)
|
||||
# add the data to the database
|
||||
for book in data:
|
||||
if type(book) != BookData:
|
||||
if not isinstance(book, BookData):
|
||||
continue
|
||||
self.db.addBookToDatabase(
|
||||
bookdata=book, app_id=app_id, prof_id=prof_id
|
||||
@@ -1083,7 +1068,7 @@ class Ui(Ui_Semesterapparat):
|
||||
if data == []:
|
||||
return
|
||||
for book in data:
|
||||
if type(book) != BookData:
|
||||
if not isinstance(book, BookData):
|
||||
continue
|
||||
self.db.addBookToDatabase(
|
||||
bookdata=book, app_id=app_id, prof_id=prof_id
|
||||
@@ -1099,10 +1084,10 @@ class Ui(Ui_Semesterapparat):
|
||||
"Bitte warten, bis alle Medien hinzugefügt wurden"
|
||||
)
|
||||
app_id = self.active_apparat
|
||||
ic(self.profdata)
|
||||
logger.debug(self.profdata)
|
||||
prof_id = self.db.getProfId(self.profdata)
|
||||
|
||||
ic(prof_id)
|
||||
logger.debug(prof_id)
|
||||
# check if apparat in database
|
||||
|
||||
# if app_id not in database, create apparat
|
||||
@@ -1110,7 +1095,7 @@ class Ui(Ui_Semesterapparat):
|
||||
if not self.db.checkApparatExistsById(app_id):
|
||||
# create apparat
|
||||
# print("Creating apparat")
|
||||
if self.btn_save_apparat(False) == False:
|
||||
if not self.btn_save_apparat(False):
|
||||
return
|
||||
created = True
|
||||
if self.dokument_list.rowCount() == 0:
|
||||
@@ -1155,7 +1140,7 @@ class Ui(Ui_Semesterapparat):
|
||||
]
|
||||
|
||||
signatures = [i for i in signatures if i != ""]
|
||||
# ic(signatures)
|
||||
# logger.debug(signatures)
|
||||
# print("starting thread")
|
||||
if prof_id is None:
|
||||
prof_id = self.db.getProfId(self.profdata)
|
||||
@@ -1218,23 +1203,29 @@ class Ui(Ui_Semesterapparat):
|
||||
if not self.validate_fields():
|
||||
self.confirm_popup("Bitte alle Pflichtfelder ausfüllen!", title="Fehler")
|
||||
return False
|
||||
appd = ApparatData()
|
||||
appd.appnr = self.active_apparat
|
||||
appd.prof_title = 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()
|
||||
prof = Prof(
|
||||
fullname=self.drpdwn_prof_name.currentText(),
|
||||
telnr=self.prof_tel_nr.text(),
|
||||
mail=self.prof_mail.text(),
|
||||
)
|
||||
prof.title = self.prof_title.text()
|
||||
apparat = Apparat(
|
||||
appnr=self.active_apparat,
|
||||
name=self.app_name.text(),
|
||||
created_semester=self.generateSemester(),
|
||||
eternal=1 if self.check_eternal_app.isChecked() else 0,
|
||||
subject=self.app_fach.currentText(),
|
||||
deleted=0,
|
||||
prof_id_adis=self.prof_id_adis.text(),
|
||||
apparat_id_adis=self.apparat_id_adis.text(),
|
||||
)
|
||||
|
||||
appd = ApparatData(prof=prof, apparat=apparat)
|
||||
|
||||
error = self.db.createApparat(appd)
|
||||
|
||||
if error:
|
||||
self.confirm_popup(error.__str__(), title="Fehler")
|
||||
return False
|
||||
if self.dokument_list.rowCount() > 0:
|
||||
self.add_files()
|
||||
if error is not None:
|
||||
@@ -1251,15 +1242,16 @@ class Ui(Ui_Semesterapparat):
|
||||
|
||||
if self.check_send_mail.isChecked():
|
||||
self.contact_prof(
|
||||
apparat=appd.appnr,
|
||||
apparat=appd.apparat.appnr,
|
||||
mail="Information zum Semesterapparat",
|
||||
location="",
|
||||
pid=appd.profname,
|
||||
pid=appd.prof.fullname,
|
||||
)
|
||||
if clear_fields:
|
||||
# print("clearing fields")
|
||||
self.__clear_fields()
|
||||
return True
|
||||
|
||||
def send_mail_preview(self):
|
||||
pass
|
||||
|
||||
@@ -1270,10 +1262,10 @@ class Ui(Ui_Semesterapparat):
|
||||
@property
|
||||
def profdata(self):
|
||||
return {
|
||||
"title":self.prof_title.text(),
|
||||
"title": self.prof_title.text(),
|
||||
"profname": self.drpdwn_prof_name.currentText(),
|
||||
"prof_mail":self.prof_mail.text(),
|
||||
"prof_tel":self.prof_tel_nr.text()
|
||||
"prof_mail": self.prof_mail.text(),
|
||||
"prof_tel": self.prof_tel_nr.text(),
|
||||
}
|
||||
|
||||
def add_files(self, prof_id=None):
|
||||
@@ -1307,9 +1299,10 @@ class Ui(Ui_Semesterapparat):
|
||||
|
||||
for apparat in self.apparats:
|
||||
self.insert_apparat_into_table(apparat)
|
||||
logger.info("Inserted {} apparats into table".format(len(self.apparats)))
|
||||
|
||||
def insert_apparat_into_table(self, apparat):
|
||||
# ic(apparat)
|
||||
# logger.debug(apparat)
|
||||
def __dauer_check(apparat):
|
||||
return "Ja" if apparat[7] == 1 else "Nein"
|
||||
|
||||
@@ -1339,7 +1332,6 @@ class Ui(Ui_Semesterapparat):
|
||||
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()
|
||||
@@ -1357,7 +1349,7 @@ class Ui(Ui_Semesterapparat):
|
||||
return
|
||||
pid = self.__get_table_data_field(self.tableWidget_apparate, pos[0], 2)
|
||||
app_id = self.__get_table_data_field(self.tableWidget_apparate, pos[0], 0)
|
||||
ic(pos, pid)
|
||||
logger.debug(pos, pid)
|
||||
extend_action.triggered.connect(self.extend_apparat)
|
||||
delete_action.triggered.connect(lambda: self.delete_apparat(pos))
|
||||
# pass pos to contact_prof
|
||||
@@ -1368,7 +1360,7 @@ class Ui(Ui_Semesterapparat):
|
||||
menu.exec(self.tableWidget_apparate.mapToGlobal(position))
|
||||
|
||||
def reminder(self):
|
||||
self.logger.log_info("Opening reminder dialog")
|
||||
logger.info("Opening reminder dialog")
|
||||
reminder = reminder_ui()
|
||||
reminder.exec()
|
||||
tableposition = self.tableWidget_apparate.currentRow()
|
||||
@@ -1385,17 +1377,17 @@ class Ui(Ui_Semesterapparat):
|
||||
self.calendarWidget.updateCells()
|
||||
# self.db.update_bookdata(data, book_id)
|
||||
# self.db.update_bookdata(data)
|
||||
self.logger.log_info("Commited message to database")
|
||||
logger.info("Commited message to database")
|
||||
# self.update_app_media_list()
|
||||
|
||||
def get_reminders(self):
|
||||
messages = self.db.getAllMessages()
|
||||
self.logger.log_info(f"Got {len(messages)} messages from database")
|
||||
logger.info(f"Got {len(messages)} messages from database")
|
||||
self.calendarWidget.setMessages(messages)
|
||||
self.calendarWidget.updateCells()
|
||||
|
||||
def open_reminder(self):
|
||||
if settings.mail.use_user_name == False:
|
||||
if not settings.mail.use_user_name:
|
||||
print("False")
|
||||
selected_date = self.calendarWidget.selectedDate().toString("yyyy-MM-dd")
|
||||
# # print(selected_date)
|
||||
@@ -1542,6 +1534,7 @@ class Ui(Ui_Semesterapparat):
|
||||
prof_id=self.db.getProfId(self.profdata),
|
||||
)
|
||||
print(medium.adis_idn, medium.signature)
|
||||
|
||||
def edit_medium(self):
|
||||
book = self.tableWidget_apparat_media.item(
|
||||
self.tableWidget_apparat_media.currentRow(), 1
|
||||
@@ -1592,7 +1585,7 @@ class Ui(Ui_Semesterapparat):
|
||||
prof_id=prof_id,
|
||||
signature=signature,
|
||||
)
|
||||
message = f'Soll das Medium "{self.tableWidget_apparat_media.item(self.tableWidget_apparat_media.currentRow(),0).text()}" wirklich gelöscht werden?'
|
||||
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, title="Löschen?")
|
||||
# print(state)
|
||||
if state == 1:
|
||||
@@ -1642,12 +1635,12 @@ class Ui(Ui_Semesterapparat):
|
||||
return
|
||||
|
||||
def __get_table_data_field(self, table, row, column):
|
||||
ic(row, column)
|
||||
logger.debug(row, column)
|
||||
row = int(row)
|
||||
return table.item(row, column).text()
|
||||
|
||||
def __contact_dialog(self, apparat, location: tuple | str, mail=None, pid=""):
|
||||
ic(location, pid, apparat)
|
||||
logger.debug(location, pid, apparat)
|
||||
|
||||
active_apparat_id = (
|
||||
self.drpdwn_app_nr.currentText() if apparat is None else apparat
|
||||
@@ -1674,7 +1667,7 @@ class Ui(Ui_Semesterapparat):
|
||||
app_subject = self.app_fach.currentText()
|
||||
else:
|
||||
app_subject = self.db.getApparatData(active_apparat_id, app_name)
|
||||
app_subject = app_subject.app_fach
|
||||
app_subject = app_subject.apparat.subject
|
||||
# profname = f"{profname.split(" ")[1]} {profname.split(" ")[0]}"
|
||||
# print(pid)
|
||||
if prof_id:
|
||||
@@ -1696,8 +1689,8 @@ class Ui(Ui_Semesterapparat):
|
||||
self.mail_thread.show()
|
||||
|
||||
def contact_prof(self, apparat="", location="", mail="", pid=""):
|
||||
ic(apparat)
|
||||
ic(location)
|
||||
logger.debug(apparat)
|
||||
logger.debug(location)
|
||||
if self.active_apparat == "":
|
||||
if apparat is False:
|
||||
self.confirm_popup(
|
||||
@@ -1733,8 +1726,8 @@ class Ui(Ui_Semesterapparat):
|
||||
def launch_gui():
|
||||
# print("trying to login")
|
||||
# print("checking if database available")
|
||||
log = MyLogger("login")
|
||||
log.log_info("Starting login dialog")
|
||||
|
||||
logger.info("Starting login dialog")
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
login_dialog = QtWidgets.QDialog()
|
||||
ui = login_ui()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from src import logger
|
||||
from PyQt6 import QtWidgets, QtCore
|
||||
from PyQt6.QtCore import QDate
|
||||
from PyQt6.QtGui import QColor, QPen
|
||||
from src.backend import Database
|
||||
import darkdetect
|
||||
from icecream import ic
|
||||
|
||||
color = "#ddfb00" if darkdetect.isDark() else "#2204ff"
|
||||
pen = QPen(QColor(color))
|
||||
@@ -22,7 +22,7 @@ class MessageCalendar(QtWidgets.QCalendarWidget):
|
||||
def getMessages(self):
|
||||
# Get the messages from the database
|
||||
messages = Database().getAllMessages()
|
||||
ic(messages)
|
||||
logger.debug(messages)
|
||||
self.setMessages(messages)
|
||||
|
||||
def deleteMessage(self, id):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
__all__ = ["filepicker"]
|
||||
from .collapse import StatusWidget
|
||||
from .filepicker import FilePicker
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from PyQt6 import QtWidgets, QtCore, QtGui
|
||||
from PyQt6.QtCore import pyqtSignal
|
||||
from .widget_sources.Ui_admin_create_user import Ui_Dialog
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
from .widget_sources.Ui_admin_edit_prof import Ui_Dialog#
|
||||
from PyQt6 import QtWidgets, QtCore
|
||||
from PyQt6.QtCore import pyqtSignal
|
||||
from icecream import ic
|
||||
from src.backend import Database
|
||||
from src import logger
|
||||
from src.logic import Prof
|
||||
from src.backend import Database
|
||||
class EditProf(QtWidgets.QDialog, Ui_Dialog):
|
||||
def __init__(self):
|
||||
super(EditProf, self).__init__()
|
||||
@@ -59,7 +60,7 @@ class EditProf(QtWidgets.QDialog, Ui_Dialog):
|
||||
else:
|
||||
self.faculty_member_old_telnr.setText(data.telnr)
|
||||
self.faculty_member_oldmail.setText(data.mail)
|
||||
ic(data)
|
||||
logger.debug(data)
|
||||
(
|
||||
self.edit_faculty_member_title.setText(data.title)
|
||||
if data.title is not None
|
||||
@@ -83,7 +84,7 @@ class EditProf(QtWidgets.QDialog, Ui_Dialog):
|
||||
olddata = self.db.getProfByName(
|
||||
self.edit_faculty_member_select_member.currentText()
|
||||
)
|
||||
ic(olddata)
|
||||
logger.debug(olddata)
|
||||
data = olddata
|
||||
oldlname = data.lastname
|
||||
oldfname = data.firstname
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
from .widget_sources.Ui_admin_edit_user import Ui_Dialog
|
||||
from PyQt6 import QtWidgets, QtCore
|
||||
from PyQt6.QtCore import pyqtSignal
|
||||
from icecream import ic
|
||||
from src.backend import Database
|
||||
from src.backend import AdminCommands
|
||||
admin = AdminCommands()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from .widget_sources.Ui_calendar_entry import Ui_Dialog
|
||||
from PyQt6 import QtWidgets, QtCore
|
||||
from PyQt6.QtCore import pyqtSignal, QDate
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# import pysignal pyslot
|
||||
from PyQt6.QtCore import pyqtSignal as Signal
|
||||
from PyQt6.QtWidgets import (
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import os
|
||||
from natsort import natsorted
|
||||
from icecream import ic
|
||||
from .widget_sources.Ui_elsa_maindialog import Ui_Dialog
|
||||
from PyQt6 import QtCore, QtWidgets, QtGui
|
||||
from PyQt6.QtGui import QRegularExpressionValidator
|
||||
from PyQt6.QtCore import QDate
|
||||
from src import Icon
|
||||
from src.backend import recreateElsaFile, generateSemesterByDate, Database
|
||||
from src.logic import elsa_word_to_csv, MyLogger, Prof
|
||||
from src.logic.log import log
|
||||
from src import Icon, logger
|
||||
from src.backend import recreateElsaFile, Semester, Database
|
||||
from src.logic import elsa_word_to_csv, Prof
|
||||
from src.ui import popus_confirm
|
||||
from src.ui.dialogs import ElsaAddEntry
|
||||
from src.ui.widgets import FilePicker
|
||||
@@ -39,6 +37,23 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
self.quote_entry.clicked.connect(self.elsa_table_entry)
|
||||
self.quote_entry.setEnabled(False)
|
||||
self.newProf.hide()
|
||||
self.splitter = QtWidgets.QSplitter(QtCore.Qt.Orientation.Horizontal)
|
||||
self.splitter.addWidget(self.media_table)
|
||||
self.splitter.addWidget(self.statistics)
|
||||
self.results.layout().removeWidget(self.media_table)
|
||||
self.results.layout().removeWidget(self.statistics)
|
||||
self.results.layout().addWidget(self.splitter)
|
||||
self.elsa_statistics_table.setColumnCount(2)
|
||||
# set header to occupy the whole width and auto scale based on table width
|
||||
self.elsa_statistics_table.horizontalHeader().setStretchLastSection(True)
|
||||
self.elsa_statistics_table.horizontalHeader().setSectionResizeMode(
|
||||
QtWidgets.QHeaderView.ResizeMode.Stretch
|
||||
)
|
||||
# if table size gets smaller, set horitzontal headers text to be left aligned
|
||||
self.elsa_statistics_table.horizontalHeader().setDefaultAlignment(
|
||||
QtCore.Qt.AlignmentFlag.AlignLeft
|
||||
)
|
||||
# self.table_elsa_list.
|
||||
Icon("person", self.prof_icon)
|
||||
# validators
|
||||
# prof mail
|
||||
@@ -55,12 +70,12 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
)
|
||||
|
||||
##Variables
|
||||
self.logger = MyLogger("ElsaDialog")
|
||||
self.db = Database()
|
||||
self.graph_data = {"x": [generateSemesterByDate()], "y": [0]}
|
||||
self.graph_data = {"x": [Semester().value], "y": [0]}
|
||||
self.createProf = False
|
||||
self.profs = self.getProfs()
|
||||
|
||||
self.elsa_prof.addItems(self.getProfs())
|
||||
self.elsa_prof.addItems([prof[0] for prof in self.profs])
|
||||
self.elsa_prof.addItem("")
|
||||
self.elsa_prof.setCurrentText("")
|
||||
# implement a check for the prof name. if name is not in list and has schema of lastname, firstname, show newProf frame
|
||||
@@ -70,7 +85,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
self.newProf_title.textChanged.connect(self.checkProfData)
|
||||
|
||||
self.loadFrame()
|
||||
log.info("Elsa Dialog loaded")
|
||||
logger.info("Elsa Dialog loaded")
|
||||
# self.show()
|
||||
|
||||
def checkProfData(self):
|
||||
@@ -84,14 +99,20 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
):
|
||||
self.elsa_save.setEnabled(True)
|
||||
self.elsa_save.setToolTip("")
|
||||
self.newProf_mail.setToolTip("")
|
||||
self.newProf_telnr.setToolTip("")
|
||||
else:
|
||||
self.elsa_save.setEnabled(False)
|
||||
self.elsa_save.setToolTip("Bitte erst Daten eingeben")
|
||||
self.newProf_mail.setToolTip("Bitte geben Sie eine gültige E-Mail ein")
|
||||
self.newProf_telnr.setToolTip(
|
||||
"Bitte geben Sie eine gültige Telefonnummer ein"
|
||||
)
|
||||
|
||||
def checkProf(self):
|
||||
if (
|
||||
", " in self.elsa_prof.currentText()
|
||||
and self.elsa_prof.currentText() not in self.getProfs()
|
||||
and self.elsa_prof.currentText() not in [prof[0] for prof in self.profs]
|
||||
):
|
||||
self.newProf.show()
|
||||
self.elsa_save.setEnabled(False)
|
||||
@@ -105,7 +126,9 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
def getProfs(self):
|
||||
profs = self.db.getProfs()
|
||||
profs = [f"{prof.lastname}, {prof.firstname}" for prof in profs]
|
||||
profs = [
|
||||
("{}, {}".format(prof.lastname, prof.firstname), prof.id) for prof in profs
|
||||
]
|
||||
|
||||
profs = list(set(profs))
|
||||
profs.sort()
|
||||
@@ -161,7 +184,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
self.elsa_date.setText(QDate.currentDate().toString("dd.MM.yyyy"))
|
||||
|
||||
def addSemester(self):
|
||||
self.elsa_semester.setText(generateSemesterByDate())
|
||||
self.elsa_semester.setText(Semester().value)
|
||||
|
||||
def update_elsa(self):
|
||||
prof = self.elsa_prof.currentText()
|
||||
@@ -205,11 +228,14 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
fullname=f"{prof.split(", ")[0]} {prof.split(", ")[1]}",
|
||||
)
|
||||
prof_id = self.db.getProfId(profdata)
|
||||
ic(profdata, prof_id)
|
||||
logger.debug(profdata, prof_id)
|
||||
|
||||
if prof_id is None:
|
||||
self.db.createProf(profdata)
|
||||
prof_id = self.db.getProfId(prof)
|
||||
self.profs.append(
|
||||
"f{}, {}".format(profdata.lastname, profdata.firstname), prof_id
|
||||
)
|
||||
elsa_id = self.db.createElsaApparat(
|
||||
date,
|
||||
prof_id,
|
||||
@@ -228,12 +254,12 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
files,
|
||||
elsa_id,
|
||||
)
|
||||
log.info("Stored {} files in the database", len(files))
|
||||
logger.info("Stored {} files in the database", len(files))
|
||||
self.cancel_elsa_creation()
|
||||
self.refresh_elsa_table()
|
||||
self.elsa_prof.setCurrentText("")
|
||||
self.quote_entry.setEnabled(False)
|
||||
log.info("Saved apparat to database, id {}", elsa_id)
|
||||
logger.info("Saved apparat to database, id {}", elsa_id)
|
||||
|
||||
def refresh_elsa_table(self):
|
||||
self.elsa_table.setRowCount(0)
|
||||
@@ -253,13 +279,13 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
def open_elsa(self):
|
||||
prof = self.elsa_table.item(self.elsa_table.currentRow(), 0).text()
|
||||
print(prof)
|
||||
logger.info("prof", prof)
|
||||
date = self.elsa_table.item(self.elsa_table.currentRow(), 1).text()
|
||||
semester = self.elsa_table.item(self.elsa_table.currentRow(), 2).text()
|
||||
self.elsa_update.setEnabled(True)
|
||||
self.elsa_save.setEnabled(False)
|
||||
if self.elsa_prof.currentText() == prof and date == self.elsa_date.text():
|
||||
self.logger.log_info("Same prof, stopping")
|
||||
logger.debug("Same prof, stopping")
|
||||
return
|
||||
self.create_frame_elsa.setEnabled(True)
|
||||
self.dokument_list_elsa.setRowCount(0)
|
||||
@@ -269,24 +295,21 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
elsa_apparats = self.db.getElsaApparats()
|
||||
elsa_id = None
|
||||
for apparat in elsa_apparats:
|
||||
print(apparat)
|
||||
if (
|
||||
apparat[1] == date
|
||||
and apparat[2] == semester
|
||||
and apparat[3] == self.db.getProfId({"profname": prof})
|
||||
):
|
||||
elsa_id = apparat[0]
|
||||
# print(elsa_id)
|
||||
break
|
||||
self.elsa_date.setText(date)
|
||||
self.elsa_semester.setText(semester)
|
||||
self.elsa_prof.setCurrentText(prof)
|
||||
ic(elsa_id)
|
||||
logger.info("Elsa ID is {}", elsa_id)
|
||||
if elsa_id is None:
|
||||
return
|
||||
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])
|
||||
@@ -340,13 +363,11 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
self.table_elsa_list.setItem(0, 11, QtWidgets.QTableWidgetItem(scan["type"]))
|
||||
|
||||
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)
|
||||
@@ -360,27 +381,6 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
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:
|
||||
# # create elsa
|
||||
# self.db.createElsaApparat(
|
||||
# self.elsa_date.text(),
|
||||
# self.elsa_prof.currentText(),
|
||||
# self.elsa_semester.text(),
|
||||
# )
|
||||
# elsa_id = self.db.getElsaId(
|
||||
# self.elsa_prof.currentText(),
|
||||
# self.elsa_semester.text(),
|
||||
# self.elsa_date.text(),
|
||||
# )
|
||||
# self.db.insertElsaFile(datalist, elsa_id)
|
||||
# self.elsa_save.setEnabled(False)
|
||||
# self.refresh_elsa_table()
|
||||
|
||||
def parseDokumentElsa(self):
|
||||
if self.dokument_list_elsa.rowCount() == 0:
|
||||
@@ -389,7 +389,6 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
# 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()
|
||||
@@ -397,14 +396,13 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
file = recreateElsaFile(
|
||||
filename=filename, filetype=filetype, open=False
|
||||
)
|
||||
# print(file)
|
||||
data, _ = elsa_word_to_csv(file)
|
||||
elsa_id = self.db.getElsaId(
|
||||
self.db.getProfId(Prof(fullname=self.elsa_prof.currentText())),
|
||||
self.elsa_semester.text(),
|
||||
self.elsa_date.text(),
|
||||
)
|
||||
ic(
|
||||
logger.debug(
|
||||
elsa_id,
|
||||
self.elsa_prof.currentText(),
|
||||
self.elsa_semester.text(),
|
||||
@@ -441,14 +439,13 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
try:
|
||||
self.elsa_statistics.removeTab(1)
|
||||
except:
|
||||
self.logger.log_debug("No tab to remove")
|
||||
logger.debug("No tab to remove")
|
||||
self.elsa_table.setRowCount(0)
|
||||
elsa_apparats = self.db.getElsaApparats()
|
||||
elsa_apparats = natsorted(elsa_apparats, key=lambda x: x[2], reverse=True)
|
||||
# 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]
|
||||
@@ -466,7 +463,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
generateMissing,
|
||||
"Anzahl der Apparate",
|
||||
)
|
||||
ic(self.graph_data)
|
||||
logger.debug(self.graph_data)
|
||||
self.elsa_statistics_table.setRowCount(0)
|
||||
for i in range(len(self.graph_data["x"])):
|
||||
self.elsa_statistics_table.insertRow(0)
|
||||
@@ -479,7 +476,7 @@ class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
|
||||
self.elsa_statistics.addTab(graph, "Graph")
|
||||
|
||||
def launch():
|
||||
log.debug("Launching Elsa Dialog")
|
||||
logger.debug("Launching Elsa Dialog")
|
||||
app = QtWidgets.QApplication([])
|
||||
window = ElsaDialog()
|
||||
window.show()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import random
|
||||
from typing import Union
|
||||
|
||||
|
||||
@@ -1,31 +1,28 @@
|
||||
from .widget_sources.Ui_search_statistic_page import Ui_Dialog
|
||||
from PyQt6 import QtWidgets, QtGui, QtCore
|
||||
from PyQt6.QtCore import pyqtSignal
|
||||
from src.backend import Database, generateSemesterByDate
|
||||
from src.logic import custom_sort, Prof
|
||||
from src import MyLogger
|
||||
from src.backend import Database, Semester
|
||||
from src import logger
|
||||
from src.logic import custom_sort, Prof, sort_semesters_list
|
||||
from src.ui import ApparatExtendDialog
|
||||
from src.ui.dialogs import Mail_Dialog
|
||||
from src.ui.widgets import DataGraph, StatusWidget
|
||||
|
||||
from natsort import natsorted
|
||||
from icecream import ic
|
||||
|
||||
|
||||
class MyComboBox(QtWidgets.QComboBox):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
|
||||
|
||||
class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
apparat_open = pyqtSignal(str)
|
||||
reloadSignal = pyqtSignal()
|
||||
refreshSignal = pyqtSignal()
|
||||
|
||||
def __init__(self):
|
||||
self.logger = MyLogger("SearchStatisticPage")
|
||||
self.logger.log_info("SearchStatisticPage started")
|
||||
logger.info("SearchStatisticPage started")
|
||||
super().__init__()
|
||||
self.setupUi(self)
|
||||
self.book_search_result.horizontalHeader().setSectionResizeMode(
|
||||
@@ -51,7 +48,14 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
self.tableWidget.resizeRowsToContents()
|
||||
self.db = Database()
|
||||
self.box_appnrs.addItems(str(i) for i in self.db.getUnavailableApparatNumbers())
|
||||
|
||||
self.splitter = QtWidgets.QSplitter(QtCore.Qt.Orientation.Horizontal)
|
||||
# insert splitter in apparatResult to allow resizing of the columns
|
||||
self.splitter.addWidget(self.app_results)
|
||||
self.splitter.addWidget(self.stats)
|
||||
self.apparatResult.layout().removeWidget(self.stats)
|
||||
self.apparatResult.layout().removeWidget(self.app_results)
|
||||
self.apparatResult.layout().addWidget(self.splitter)
|
||||
self.semester = Semester().value
|
||||
self.populate_tab()
|
||||
|
||||
def restore_apparat(self):
|
||||
@@ -90,15 +94,15 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
extend.exec()
|
||||
if extend.result() == QtWidgets.QDialog.DialogCode.Accepted:
|
||||
data = extend.get_data()
|
||||
ic(data)
|
||||
logger.debug(data)
|
||||
app_name = self.tableWidget.item(self.tableWidget.currentRow(), 1).text()
|
||||
app_id = self.db.getApparatId(app_name)
|
||||
self.db.setNewSemesterDate(app_id, data["semester"], data["dauerapp"])
|
||||
#remove the row
|
||||
# remove the row
|
||||
self.tableWidget.removeRow(self.tableWidget.currentRow())
|
||||
self.refreshSignal.emit()
|
||||
def tabW2_changed(self):
|
||||
|
||||
def tabW2_changed(self):
|
||||
if self.tabWidget_2.currentIndex() == 0:
|
||||
self.stackedWidget_4.setCurrentIndex(0)
|
||||
else:
|
||||
@@ -113,12 +117,11 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
"title": title if title != "" else None,
|
||||
}
|
||||
params = {key: value for key, value in params.items() if value is not None}
|
||||
# ic(params)
|
||||
logger.debug(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)
|
||||
@@ -145,10 +148,9 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
selected_apparats.append(data)
|
||||
# delete all selected apparats
|
||||
ic(selected_apparats)
|
||||
logger.debug(selected_apparats)
|
||||
dialogs = []
|
||||
for i in selected_apparats:
|
||||
|
||||
app_id = i["app_id"]
|
||||
app_name = i["app_name"]
|
||||
prof_name = i["prof_name"]
|
||||
@@ -206,7 +208,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
self.box_dauerapp.setEnabled(True)
|
||||
|
||||
def populate_tab(self, table_or_graph=0):
|
||||
self.logger.log_info("populate_tab started")
|
||||
logger.info("populate_tab started")
|
||||
# add default values to the dropdowns
|
||||
self.box_appnrs.clear()
|
||||
self.box_appnrs.addItem("")
|
||||
@@ -232,9 +234,13 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
apparats = [str(apparat) for apparat in apparats]
|
||||
self.box_appnrs.addItems(apparats)
|
||||
persons = self.db.getProfs()
|
||||
self.box_person.addItems([f"{person.lastname}, {person.firstname}" for person in persons])
|
||||
persons = sorted(persons, key=lambda x: x.lastname)
|
||||
self.box_person.addItems(
|
||||
[f"{person.lastname}, {person.firstname}" for person in persons]
|
||||
)
|
||||
self.box_fach.addItems(subject[1] for subject in self.db.getSubjects())
|
||||
semester = self.db.getSemersters()
|
||||
semester = self.db.getSemesters()
|
||||
semester = sort_semesters_list(semester)
|
||||
self.box_erstellsemester.addItems(semester)
|
||||
self.box_semester.addItems(semester)
|
||||
self.statistics_table.setRowCount(0)
|
||||
@@ -269,7 +275,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
# place the graph into tabWidget_3
|
||||
self.tabWidget_3.addTab(graph, "Graph")
|
||||
self.tabWidget_3.setCurrentIndex(table_or_graph)
|
||||
self.logger.log_info("populate_tab finished")
|
||||
logger.info("populate_tab finished")
|
||||
|
||||
def delete_selected_apparats(self):
|
||||
# get all selected apparats
|
||||
@@ -281,9 +287,9 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
selected_apparat_rows.append(i)
|
||||
# delete all selected apparats
|
||||
# # print(selected_apparats)
|
||||
self.logger.log_info(f"Deleting apparats: {selected_apparats}")
|
||||
logger.info(f"Deleting apparats: {selected_apparats}")
|
||||
for apparat in selected_apparats:
|
||||
self.db.deleteApparat(apparat, generateSemesterByDate())
|
||||
self.db.deleteApparat(apparat, self.semester)
|
||||
for row in selected_apparat_rows:
|
||||
# set the background of the row to red
|
||||
for j in range(5):
|
||||
@@ -295,10 +301,10 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
def statistics(self):
|
||||
"""Generate the statistics based on the selected filters."""
|
||||
self.tableWidget.setRowCount(0)
|
||||
active_semseter = generateSemesterByDate()
|
||||
active_semseter = self.semester
|
||||
self.db_err_message.setText("")
|
||||
self.btn_del_select_apparats.setEnabled(True)
|
||||
self.btn_notify_for_deletion.setEnabled(True)
|
||||
self.btn_del_select_apparats.setEnabled(False)
|
||||
self.btn_notify_for_deletion.setEnabled(False)
|
||||
params = {
|
||||
"appnr": (
|
||||
self.box_appnrs.currentText()
|
||||
@@ -306,7 +312,7 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
else None
|
||||
),
|
||||
"prof_id": (
|
||||
self.db.getProfId(self.box_person.currentText())
|
||||
self.db.getProfId(Prof(fullname=self.box_person.currentText()))
|
||||
if self.box_person.currentText() != ""
|
||||
else None
|
||||
),
|
||||
@@ -348,29 +354,22 @@ class SearchStatisticPage(QtWidgets.QDialog, Ui_Dialog):
|
||||
self.db_err_message.setText("Keine Ergebnisse gefunden")
|
||||
return
|
||||
data = []
|
||||
sem_year = active_semseter.split(" ")[1]
|
||||
sem_time = active_semseter.split(" ")[0]
|
||||
if sem_time == "WiSe":
|
||||
sem_year = int(sem_year.split("/")[0])
|
||||
else:
|
||||
sem_year = int(sem_year)
|
||||
|
||||
for entry in result:
|
||||
if "deletable" in params.keys():
|
||||
entry_sem_time = entry[5].split(" ")[0]
|
||||
entry_sem_year = entry[5].split(" ")[1]
|
||||
if entry_sem_time == "SoSe":
|
||||
entry_sem_year = int(entry_sem_year)
|
||||
if (entry_sem_year < sem_year) or (
|
||||
sem_time == "WiSe" and entry_sem_year == sem_year
|
||||
):
|
||||
data.append(entry)
|
||||
else:
|
||||
entry_sem_year = int(entry_sem_year.split("/")[0])
|
||||
if entry_sem_year < sem_year:
|
||||
data.append(entry)
|
||||
sem = Semester().from_string(
|
||||
entry[8] if entry[8] is not None else entry[5]
|
||||
)
|
||||
logger.info(f"Semester: {sem}")
|
||||
if sem.isPastSemester(Semester()):
|
||||
data.append(entry)
|
||||
else:
|
||||
data.append(entry)
|
||||
self.tableWidget.setRowCount(len(data))
|
||||
if len(data) > 0:
|
||||
self.btn_del_select_apparats.setEnabled(True)
|
||||
self.btn_notify_for_deletion.setEnabled(True)
|
||||
|
||||
for i in range(len(data)):
|
||||
# set the items 0 = clickable checkbox, 1 = appname, 2 = profname, 3 = fach
|
||||
self.tableWidget.setItem(i, 0, QtWidgets.QTableWidgetItem(""))
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\widgets\widget_sources\admin_create_user.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\widgets\widget_sources\admin_edit_prof.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\widgets\widget_sources\admin_edit_user.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\widgets\widget_sources\calendar_entry.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\widgets\widget_sources\elsa_maindialog.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
@@ -187,15 +188,36 @@ class Ui_Dialog(object):
|
||||
self.verticalLayout.addWidget(self.create_frame_elsa)
|
||||
self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_6.setObjectName("horizontalLayout_6")
|
||||
self.quote_entry = QtWidgets.QPushButton(parent=Dialog)
|
||||
self.quote_entry.setObjectName("quote_entry")
|
||||
self.horizontalLayout_6.addWidget(self.quote_entry)
|
||||
spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
|
||||
self.horizontalLayout_6.addItem(spacerItem5)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_6)
|
||||
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
|
||||
self.table_elsa_list = QtWidgets.QTableWidget(parent=Dialog)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_5)
|
||||
self.results = QtWidgets.QWidget(parent=Dialog)
|
||||
self.results.setObjectName("results")
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.results)
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.statistics = QtWidgets.QWidget(parent=self.results)
|
||||
self.statistics.setObjectName("statistics")
|
||||
self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.statistics)
|
||||
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
|
||||
self.media_table = QtWidgets.QWidget(parent=self.statistics)
|
||||
self.media_table.setObjectName("media_table")
|
||||
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.media_table)
|
||||
self.verticalLayout_4.setObjectName("verticalLayout_4")
|
||||
self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_9.setObjectName("horizontalLayout_9")
|
||||
self.quote_entry = QtWidgets.QPushButton(parent=self.media_table)
|
||||
self.quote_entry.setObjectName("quote_entry")
|
||||
self.horizontalLayout_9.addWidget(self.quote_entry)
|
||||
spacerItem5 = QtWidgets.QSpacerItem(
|
||||
40,
|
||||
20,
|
||||
QtWidgets.QSizePolicy.Policy.Expanding,
|
||||
QtWidgets.QSizePolicy.Policy.Minimum,
|
||||
)
|
||||
self.horizontalLayout_9.addItem(spacerItem5)
|
||||
self.verticalLayout_4.addLayout(self.horizontalLayout_9)
|
||||
self.table_elsa_list = QtWidgets.QTableWidget(parent=self.media_table)
|
||||
self.table_elsa_list.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
|
||||
self.table_elsa_list.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
|
||||
self.table_elsa_list.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectItems)
|
||||
@@ -230,13 +252,14 @@ class Ui_Dialog(object):
|
||||
self.table_elsa_list.setHorizontalHeaderItem(11, item)
|
||||
self.table_elsa_list.horizontalHeader().setDefaultSectionSize(85)
|
||||
self.table_elsa_list.horizontalHeader().setMinimumSectionSize(31)
|
||||
self.horizontalLayout_5.addWidget(self.table_elsa_list)
|
||||
self.elsa_statistics = QtWidgets.QTabWidget(parent=Dialog)
|
||||
self.verticalLayout_4.addWidget(self.table_elsa_list)
|
||||
self.horizontalLayout_7.addWidget(self.media_table)
|
||||
self.elsa_statistics = QtWidgets.QTabWidget(parent=self.statistics)
|
||||
self.elsa_statistics.setObjectName("elsa_statistics")
|
||||
self.tab = QtWidgets.QWidget()
|
||||
self.tab.setObjectName("tab")
|
||||
self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.tab)
|
||||
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
|
||||
self.horizontalLayout_8 = QtWidgets.QHBoxLayout(self.tab)
|
||||
self.horizontalLayout_8.setObjectName("horizontalLayout_8")
|
||||
self.elsa_statistics_table = QtWidgets.QTableWidget(parent=self.tab)
|
||||
self.elsa_statistics_table.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
|
||||
self.elsa_statistics_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
@@ -250,14 +273,16 @@ class Ui_Dialog(object):
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.elsa_statistics_table.setHorizontalHeaderItem(1, item)
|
||||
self.elsa_statistics_table.horizontalHeader().setDefaultSectionSize(169)
|
||||
self.horizontalLayout_7.addWidget(self.elsa_statistics_table)
|
||||
self.horizontalLayout_8.addWidget(self.elsa_statistics_table)
|
||||
self.elsa_statistics.addTab(self.tab, "")
|
||||
self.horizontalLayout_5.addWidget(self.elsa_statistics)
|
||||
self.horizontalLayout_5.setStretch(0, 7)
|
||||
self.horizontalLayout_5.setStretch(1, 3)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_5)
|
||||
self.horizontalLayout_7.addWidget(self.elsa_statistics)
|
||||
self.horizontalLayout_3.addWidget(self.statistics)
|
||||
self.results_table = QtWidgets.QWidget(parent=self.results)
|
||||
self.results_table.setObjectName("results_table")
|
||||
self.horizontalLayout_3.addWidget(self.results_table)
|
||||
self.verticalLayout.addWidget(self.results)
|
||||
self.verticalLayout.setStretch(0, 1)
|
||||
self.verticalLayout.setStretch(3, 2)
|
||||
self.verticalLayout.setStretch(4, 2)
|
||||
|
||||
self.retranslateUi(Dialog)
|
||||
self.elsa_statistics.setCurrentIndex(0)
|
||||
@@ -277,12 +302,8 @@ class Ui_Dialog(object):
|
||||
Dialog.setTabOrder(self.seperateEntries, self.check_file_elsa)
|
||||
Dialog.setTabOrder(self.check_file_elsa, self.elsa_save)
|
||||
Dialog.setTabOrder(self.elsa_save, self.elsa_update)
|
||||
Dialog.setTabOrder(self.elsa_update, self.quote_entry)
|
||||
Dialog.setTabOrder(self.quote_entry, self.elsa_statistics)
|
||||
Dialog.setTabOrder(self.elsa_statistics, self.table_elsa_list)
|
||||
Dialog.setTabOrder(self.table_elsa_list, self.elsa_table)
|
||||
Dialog.setTabOrder(self.elsa_table, self.elsa_statistics_table)
|
||||
Dialog.setTabOrder(self.elsa_statistics_table, self.dokument_list_elsa)
|
||||
Dialog.setTabOrder(self.elsa_update, self.elsa_table)
|
||||
Dialog.setTabOrder(self.elsa_table, self.dokument_list_elsa)
|
||||
|
||||
def retranslateUi(self, Dialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\widgets\widget_sources\search_statistic_page.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.7.1
|
||||
@@ -12,7 +13,7 @@ from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
class Ui_Dialog(object):
|
||||
def setupUi(self, Dialog):
|
||||
Dialog.setObjectName("Dialog")
|
||||
Dialog.resize(1244, 767)
|
||||
Dialog.resize(1250, 767)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.tabWidget_2 = QtWidgets.QTabWidget(parent=Dialog)
|
||||
@@ -150,24 +151,26 @@ class Ui_Dialog(object):
|
||||
self.apparatResult.setObjectName("apparatResult")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.apparatResult)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.verticalLayout_4 = QtWidgets.QVBoxLayout()
|
||||
self.verticalLayout_4.setObjectName("verticalLayout_4")
|
||||
self.app_results = QtWidgets.QWidget(parent=self.apparatResult)
|
||||
self.app_results.setObjectName("app_results")
|
||||
self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.app_results)
|
||||
self.verticalLayout_7.setObjectName("verticalLayout_7")
|
||||
self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
|
||||
self.verticalLayout_5 = QtWidgets.QVBoxLayout()
|
||||
self.verticalLayout_5.setObjectName("verticalLayout_5")
|
||||
self.horizontalLayout_7.addLayout(self.verticalLayout_5)
|
||||
self.btn_del_select_apparats = QtWidgets.QPushButton(parent=self.apparatResult)
|
||||
self.btn_del_select_apparats = QtWidgets.QPushButton(parent=self.app_results)
|
||||
self.btn_del_select_apparats.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus)
|
||||
self.btn_del_select_apparats.setObjectName("btn_del_select_apparats")
|
||||
self.horizontalLayout_7.addWidget(self.btn_del_select_apparats)
|
||||
self.btn_notify_for_deletion = QtWidgets.QPushButton(parent=self.apparatResult)
|
||||
self.btn_notify_for_deletion = QtWidgets.QPushButton(parent=self.app_results)
|
||||
self.btn_notify_for_deletion.setObjectName("btn_notify_for_deletion")
|
||||
self.horizontalLayout_7.addWidget(self.btn_notify_for_deletion)
|
||||
spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
|
||||
self.horizontalLayout_7.addItem(spacerItem4)
|
||||
self.verticalLayout_4.addLayout(self.horizontalLayout_7)
|
||||
self.tableWidget = QtWidgets.QTableWidget(parent=self.apparatResult)
|
||||
self.verticalLayout_7.addLayout(self.horizontalLayout_7)
|
||||
self.tableWidget = QtWidgets.QTableWidget(parent=self.app_results)
|
||||
self.tableWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
|
||||
self.tableWidget.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
|
||||
self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
|
||||
@@ -185,14 +188,18 @@ class Ui_Dialog(object):
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.tableWidget.setHorizontalHeaderItem(4, item)
|
||||
self.tableWidget.horizontalHeader().setStretchLastSection(True)
|
||||
self.verticalLayout_4.addWidget(self.tableWidget)
|
||||
self.horizontalLayout.addLayout(self.verticalLayout_4)
|
||||
self.tabWidget_3 = QtWidgets.QTabWidget(parent=self.apparatResult)
|
||||
self.verticalLayout_7.addWidget(self.tableWidget)
|
||||
self.horizontalLayout.addWidget(self.app_results)
|
||||
self.stats = QtWidgets.QWidget(parent=self.apparatResult)
|
||||
self.stats.setObjectName("stats")
|
||||
self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.stats)
|
||||
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
|
||||
self.tabWidget_3 = QtWidgets.QTabWidget(parent=self.stats)
|
||||
self.tabWidget_3.setObjectName("tabWidget_3")
|
||||
self.statistic_table = QtWidgets.QWidget()
|
||||
self.statistic_table.setObjectName("statistic_table")
|
||||
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.statistic_table)
|
||||
self.verticalLayout_6.setObjectName("verticalLayout_6")
|
||||
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.statistic_table)
|
||||
self.verticalLayout_4.setObjectName("verticalLayout_4")
|
||||
self.statistics_table = QtWidgets.QTableWidget(parent=self.statistic_table)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
@@ -219,17 +226,16 @@ class Ui_Dialog(object):
|
||||
self.statistics_table.horizontalHeader().setSortIndicatorShown(True)
|
||||
self.statistics_table.horizontalHeader().setStretchLastSection(False)
|
||||
self.statistics_table.verticalHeader().setStretchLastSection(True)
|
||||
self.verticalLayout_6.addWidget(self.statistics_table)
|
||||
self.verticalLayout_4.addWidget(self.statistics_table)
|
||||
self.dataLayout = QtWidgets.QHBoxLayout()
|
||||
self.dataLayout.setObjectName("dataLayout")
|
||||
self.verticalLayout_6.addLayout(self.dataLayout)
|
||||
self.verticalLayout_4.addLayout(self.dataLayout)
|
||||
self.tabWidget_3.addTab(self.statistic_table, "")
|
||||
self.graph_table = QtWidgets.QWidget()
|
||||
self.graph_table.setObjectName("graph_table")
|
||||
self.tabWidget_3.addTab(self.graph_table, "")
|
||||
self.horizontalLayout.addWidget(self.tabWidget_3)
|
||||
self.horizontalLayout.setStretch(0, 55)
|
||||
self.horizontalLayout.setStretch(1, 45)
|
||||
self.horizontalLayout_5.addWidget(self.tabWidget_3)
|
||||
self.horizontalLayout.addWidget(self.stats)
|
||||
self.stackedWidget_4.addWidget(self.apparatResult)
|
||||
self.bookresult = QtWidgets.QWidget()
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
|
||||
@@ -285,8 +291,7 @@ class Ui_Dialog(object):
|
||||
Dialog.setTabOrder(self.box_dauerapp, self.btn_search)
|
||||
Dialog.setTabOrder(self.btn_search, self.btn_del_select_apparats)
|
||||
Dialog.setTabOrder(self.btn_del_select_apparats, self.btn_notify_for_deletion)
|
||||
Dialog.setTabOrder(self.btn_notify_for_deletion, self.tabWidget_3)
|
||||
Dialog.setTabOrder(self.tabWidget_3, self.book_search_result)
|
||||
Dialog.setTabOrder(self.btn_notify_for_deletion, self.book_search_result)
|
||||
Dialog.setTabOrder(self.book_search_result, self.seach_by_signature)
|
||||
Dialog.setTabOrder(self.seach_by_signature, self.search_by_title)
|
||||
Dialog.setTabOrder(self.search_by_title, self.book_search)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
from .blob import create_blob
|
||||
from .icon import Icon
|
||||
from .pickles import dump_pickle, load_pickle
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
def create_blob(file):
|
||||
"""
|
||||
Creates a blob from a file.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import darkdetect
|
||||
from omegaconf import OmegaConf
|
||||
from PyQt6 import QtGui
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import pickle
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user