Merge pull request 'dev_database_issue' (#11) from dev_database_issue into dev

Reviewed-on: #11
This commit was merged in pull request #11.
This commit is contained in:
2025-06-24 12:47:11 +01:00
11 changed files with 752 additions and 461 deletions

View File

@@ -1,4 +1,4 @@
from typing import Optional, Any
from typing import Optional, Any, Union
from dataclasses import dataclass
from omegaconf import OmegaConf, DictConfig
import os
@@ -31,8 +31,8 @@ class Zotero:
@dataclass
class Database:
name: str
path: str | Path
temp: str | Path
path: Union[str, Path, None]
temp: Union[str, Path, None]
def getattr(self, name: str):
return getattr(self, name)

View File

@@ -19,6 +19,11 @@ if not os.path.exists(CONFIG_DIR):
settings = Config(f"{CONFIG_DIR}/config.yaml")
DATABASE_DIR = (
app.user_config_dir if settings.database.path is None else settings.database.path
)
if not os.path.exists(DATABASE_DIR):
os.makedirs(DATABASE_DIR)
first_launch = settings.exists
if not os.path.exists(settings.database.temp.expanduser()):
settings.database.temp.expanduser().mkdir(parents=True, exist_ok=True)

View File

@@ -2,6 +2,14 @@ import hashlib
import random
from .database import Database
import loguru
import sys
from src import LOG_DIR
log = loguru.logger
log.remove()
log.add(sys.stdout, level="INFO")
log.add(f"{LOG_DIR}/application.log", rotation="1 MB", retention="10 days")
# change passwords for apparats, change passwords for users, list users, create and delete users etc
@@ -9,9 +17,14 @@ from .database import Database
class AdminCommands:
"""Basic Admin commands for the admin console. This class is used to create, delete, and list users. It also has the ability to change passwords for users."""
def __init__(self):
"""Defaulf Constructor for the AdminCommands class."""
self.db = Database()
def __init__(self, db_path=None):
"""Default Constructor for the AdminCommands class."""
if db_path is None:
self.db = Database()
else:
self.db = Database(db_path=db_path)
log.info("AdminCommands initialized with database connection.")
log.critical("location: {}", self.db.db_path)
def create_password(self, password: str) -> tuple[str, str]:
"""Create a hashed password and a salt for the password.
@@ -44,7 +57,7 @@ class AdminCommands:
hashed_password = self.hash_password("admin")
self.db.createUser("admin", salt + hashed_password, "admin", salt)
def create_user(self, username: str, password: str, role: str = "user"):
def create_user(self, username: str, password: str, role: str = "user") -> bool:
"""Create a new user in the database.
Args:
@@ -53,9 +66,10 @@ class AdminCommands:
role (str, optional): the role of the user to be created. Defaults to "user".
"""
hashed_password, salt = self.create_password(password)
self.db.createUser(
status = self.db.createUser(
user=username, password=salt + hashed_password, role=role, salt=salt
)
return status
def hash_password(self, password: str) -> str:
"""Hash a password using SHA256.

View File

@@ -12,7 +12,7 @@ from typing import Any, List, Optional, Tuple, Union
import loguru
from src import LOG_DIR, settings
from src import LOG_DIR, settings, DATABASE_DIR
from src.backend.db import (
CREATE_ELSA_FILES_TABLE,
CREATE_ELSA_MEDIA_TABLE,
@@ -44,12 +44,11 @@ ascii_lowercase = lower + digits + punctuation
# get the line that called the function
class Database:
database = settings.database
"""
Initialize the database and create the tables if they do not exist.
"""
def __init__(self, db_path: Path = None):
def __init__(self, db_path: Union[Path, None] = None):
"""
Default constructor for the database class
@@ -57,15 +56,32 @@ class Database:
db_path (str, optional): Optional Path for testing / specific purposes. Defaults to None.
"""
if db_path is None:
self.db_path = Path(self.database.path.expanduser(), self.database.name)
if settings.database.path is not None:
self.db_path = Path(
settings.database.path.expanduser(), settings.database.name
)
else:
self.db_path = None
# self.db_path = self.db_path.replace("~", str(Path.home()))
log.debug(self.db_path)
else:
self.db_path = db_path
self.checkDatabaseStatus()
log.debug(f"Database path: {self.db_path}")
self.db_initialized = False
def initializeDatabase(self):
if not self.db_initialized:
self.checkDatabaseStatus()
self.db_initialized = True
def overwritePath(self, new_db_path: str):
log.debug("got new path, overwriting")
self.db_path = Path(new_db_path)
def checkDatabaseStatus(self):
path = self.database.path.expanduser()
path = settings.database.path
if path is None:
path = Path(DATABASE_DIR)
# path = path.replace("~", str(Path.home()))
# path = os.path.abspath(path)
if not os.path.exists(path):
@@ -509,7 +525,7 @@ class Database:
str: The filename of the recreated file
"""
blob = self.getBlob(filename, app_id)
tempdir = self.database.temp.expanduser()
tempdir = settings.database.temp.expanduser()
if not tempdir.exists():
tempdir.mkdir(parents=True, exist_ok=True)
file = tempfile.NamedTemporaryFile(
@@ -1280,6 +1296,13 @@ class Database:
"INSERT OR IGNORE INTO user (username, password, role, salt) VALUES (?,?,?,?)",
(user, password, role, salt),
)
# check if user was created
return (
self.query_db(
"SELECT username FROM user WHERE username=?", (user,), one=True
)
is not None
)
def deleteUser(self, user):
"""delete an unser
@@ -1467,7 +1490,7 @@ class Database:
"SELECT fileblob FROM elsa_files WHERE filename=?", (filename,), one=True
)[0]
# log.debug(blob)
tempdir = self.database.temp.expanduser()
tempdir = settings.database.temp.expanduser()
if not tempdir.exists():
tempdir.mkdir(parents=True, exist_ok=True)

View File

@@ -1,5 +1,22 @@
import datetime
"""Semester helper class
A small utility around the *German* academic calendar that distinguishes
between *Wintersemester* (WiSe) and *Sommersemester* (SoSe).
Key points
----------
* A **`Semester`** is identified by a *term* ("SoSe" or "WiSe") and the last two
digits of the calendar year in which the term *starts*.
* Formatting **never** pads the year with a leading zero so ``6`` stays ``6``.
* ``offset(n)`` and the static ``generate_missing`` reliably walk the timeline
one semester at a time with correct year transitions:
SoSe 6 → **WiSe 6/7** → SoSe 7 → WiSe 7/8 → …
"""
from __future__ import annotations
import datetime
import re
from dataclasses import dataclass
import loguru
import sys
@@ -11,136 +28,215 @@ log.add(f"{LOG_DIR}/application.log", rotation="1 MB", retention="10 days")
@dataclass
# @dataclass
class Semester:
log.debug("Semester class loaded")
"""Represents a German university semester (WiSe or SoSe)."""
_year: int | None = str(datetime.datetime.now().year)[2:]
_semester: str | None = None
# ------------------------------------------------------------------
# Classlevel defaults will be *copied* to each instance and then
# potentially overwritten in ``__init__``.
# ------------------------------------------------------------------
_year: int | None = int(str(datetime.datetime.now().year)[2:]) # 24 → 24
_semester: str | None = None # "WiSe" or "SoSe" set later
_month: int | None = datetime.datetime.now().month
value: str = None
log.debug(
f"Initialized Semester class with values: month: {_month}, semester: {_semester}, year {_year}"
)
value: str | None = None # Humanreadable label, e.g. "WiSe 23/24"
def __post_init__(self):
if isinstance(self._year, str):
self._year = int(self._year)
# ------------------------------------------------------------------
# Construction helpers
# ------------------------------------------------------------------
def __init__(
self,
year: int | None = None,
semester: str | None = None,
month: int | None = None,
) -> None:
if year is not None:
self._year = int(year)
if semester is not None:
if semester not in ("WiSe", "SoSe"):
raise ValueError("semester must be 'WiSe' or 'SoSe'")
self._semester = semester
if month is not None:
self._month = month
self.__post_init__()
def __post_init__(self) -> None: # noqa: D401 keep original name
if self._year is None:
self._year = datetime.datetime.now().year[2:]
self._year = int(str(datetime.datetime.now().year)[2:])
if self._month is None:
self._month = datetime.datetime.now().month
if self._semester is None:
self.generateSemester()
self.computeValue()
self._generate_semester_from_month()
self._compute_value()
def __str__(self):
return self.value
# ------------------------------------------------------------------
# Dunder helpers
# ------------------------------------------------------------------
def __str__(self) -> str: # noqa: D401 keep original name
return self.value or "<invalid Semester>"
def generateSemester(self):
if self._month <= 3 or self._month > 9:
self._semester = "WiSe"
else:
self._semester = "SoSe"
def __repr__(self) -> str: # Helpful for debugging lists
return f"Semester({self._year!r}, {self._semester!r})"
@log.catch
def computeValue(self):
# year is only last two digits
# ------------------------------------------------------------------
# Internal helpers
# ------------------------------------------------------------------
def _generate_semester_from_month(self) -> None:
"""Infer *WiSe* / *SoSe* from the month attribute."""
self._semester = "WiSe" if (self._month <= 3 or self._month > 9) else "SoSe"
def _compute_value(self) -> None:
"""Humanreadable semester label e.g. ``WiSe 23/24`` or ``SoSe 24``."""
year = self._year
valueyear = str(year)
if self._semester == "WiSe":
if self._month < 4:
valueyear = str(year - 1) + "/" + str(year)
else:
valueyear = str(year) + "/" + str(year + 1)
self.value = f"{self._semester} {valueyear}"
next_year = (year + 1) % 100 # wrap 99 → 0
self.value = f"WiSe {year}/{next_year}"
else: # SoSe
self.value = f"SoSe {year}"
@log.catch
def offset(self, value: int) -> str:
"""Generate a new Semester object by offsetting the current semester by a given value
# ------------------------------------------------------------------
# Public API
# ------------------------------------------------------------------
def offset(self, value: int) -> "Semester":
"""Return a new :class:`Semester` *value* steps away.
Args:
value (int): The value by which the semester should be offset
The algorithm maps every semester to a monotonically increasing
*linear index* so that simple addition suffices:
Returns:
str: the new semester value
``index = year * 2 + (0 if SoSe else 1)``.
"""
assert isinstance(value, int), "Value must be an integer"
if not isinstance(value, int):
raise TypeError("value must be an int (number of semesters to jump)")
if value == 0:
return self
if value > 0:
if value % 2 == 0:
return Semester(
self._year - value // 2, self._semester - value // 2 + 1
)
else:
semester = self._semester
semester = "SoSe" if semester == "WiSe" else "WiSe"
return Semester(self._year + value // 2, semester)
else:
if value % 2 == 0:
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)
return Semester(self._year, self._semester)
def isPastSemester(self, semester) -> bool:
"""Checks if the current Semester is a past Semester compared to the given Semester
current_idx = self._year * 2 + (0 if self._semester == "SoSe" else 1)
target_idx = current_idx + value
if target_idx < 0:
raise ValueError("offset would result in a negative year not supported")
Args:
semester (str): The semester to compare to
new_year, semester_bit = divmod(target_idx, 2)
new_semester = "SoSe" if semester_bit == 0 else "WiSe"
return Semester(new_year, new_semester)
Returns:
bool: True if the current semester is in the past, False otherwise
"""
if self.year < semester.year:
# ------------------------------------------------------------------
# Comparison helpers
# ------------------------------------------------------------------
def isPastSemester(self, other: "Semester") -> bool:
if self.year < other.year:
return True
if self.year == semester.year:
if self.semester == "WiSe" and semester.semester == "SoSe":
return True
if self.year == other.year:
return (
self.semester == "WiSe" and other.semester == "SoSe"
) # WiSe before next SoSe
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:
def isFutureSemester(self, other: "Semester") -> bool:
if self.year > other.year:
return True
if self.year == semester.year:
if self.semester == "SoSe" and semester.semester == "WiSe":
return True
if self.year == other.year:
return (
self.semester == "SoSe" and other.semester == "WiSe"
) # SoSe after WiSe of same year
return False
def from_string(self, val: str):
if " " in val:
values = val.split(" ")
if len(values) != 2:
raise ValueError("Invalid semester format")
self._semester = values[0]
if len(values[1]) == 4:
self._year = int(values[1][2:])
# self._year = int(values[1])
self.computeValue()
return self
def isMatch(self, other: "Semester") -> bool:
return self.year == other.year and self.semester == other.semester
# ------------------------------------------------------------------
# Convenience properties
# ------------------------------------------------------------------
@property
def next(self):
def next(self) -> "Semester":
return self.offset(1)
@property
def previous(self):
def previous(self) -> "Semester":
return self.offset(-1)
@property
def year(self):
def year(self) -> int:
return self._year
@property
def semester(self):
def semester(self) -> str:
return self._semester
# ------------------------------------------------------------------
# Static helpers
# ------------------------------------------------------------------
@staticmethod
def generate_missing(start: "Semester", end: "Semester") -> list[str]:
"""Return all consecutive semesters from *start* to *end* (inclusive)."""
if not isinstance(start, Semester) or not isinstance(end, Semester):
raise TypeError("start and end must be Semester instances")
if start.isFutureSemester(end) and not start.isMatch(end):
raise ValueError("'start' must not be after 'end'")
chain: list[Semester] = [start.value]
current = start
while not current.isMatch(end):
current = current.next
chain.append(current.value)
if len(chain) > 1000: # sanity guard
raise RuntimeError("generate_missing exceeded sane iteration limit")
return chain
# ------------------------------------------------------------------
# Parsing helper
# ------------------------------------------------------------------
@classmethod
def from_string(cls, s: str) -> "Semester":
"""Parse a humanreadable semester label and return a :class:`Semester`.
Accepted formats (caseinsensitive)::
"SoSe <YY>" → SoSe of year YY
"WiSe <YY>/<YY+1>" → Winter term starting in YY
"WiSe <YY>" → Shorthand for the above (next year implied)
``YY`` may contain a leading zero ("06" → 6).
"""
if not isinstance(s, str):
raise TypeError("s must be a string")
pattern = r"\s*(WiSe|SoSe)\s+(\d{1,2})(?:\s*/\s*(\d{1,2}))?\s*"
m = re.fullmatch(pattern, s, flags=re.IGNORECASE)
if not m:
raise ValueError(
"invalid semester string format expected 'SoSe YY' or 'WiSe YY/YY' (spacing flexible)"
)
term_raw, y1_str, y2_str = m.groups()
term = term_raw.capitalize() # normalize case → "WiSe" or "SoSe"
year = int(y1_str.lstrip("0") or "0") # "06" → 6, "0" stays 0
if term == "SoSe":
if y2_str is not None:
raise ValueError(
"SoSe string should not contain '/' followed by a second year"
)
return cls(year, "SoSe")
# term == "WiSe"
if y2_str is not None:
next_year = int(y2_str.lstrip("0") or "0")
expected_next = (year + 1) % 100
if next_year != expected_next:
raise ValueError("WiSe second year must equal first year + 1 (mod 100)")
# Accept both explicit "WiSe 6/7" and shorthand "WiSe 6"
return cls(year, "WiSe")
# ------------------------- quick selftest -------------------------
if __name__ == "__main__":
# Chain generation demo ------------------------------------------------
s_start = Semester(6, "SoSe") # SoSe 6
s_end = Semester(25, "WiSe") # WiSe 25/26
chain = Semester.generate_missing(s_start, s_end)
print("generate_missing:", [str(s) for s in chain])
# Parsing demo ---------------------------------------------------------
for label in ["SoSe 6", "WiSe 6/7", "wise 23/24", "WiSe 9"]:
print("from_string:", label, "", Semester.from_string(label))

View File

@@ -5,7 +5,6 @@ import loguru
from PySide6 import QtCore, QtWidgets
from src import LOG_DIR, Icon
from src.backend.admin_console import AdminCommands
from src.backend.database import Database
from .dialog_sources.login_ui import Ui_Dialog
@@ -51,6 +50,7 @@ class LoginDialog(Ui_Dialog):
self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
self.lineEdit_2.setClearButtonEnabled(True)
self.lineEdit_2.setObjectName("lineEdit_2")
log.info("Calling database")
self.db = Database()
self.retranslateUi(Dialog)
@@ -75,6 +75,8 @@ class LoginDialog(Ui_Dialog):
hashed_password = hashlib.sha256(password.encode()).hexdigest()
if len(self.db.getUsers()) == 0:
from src.backend.admin_console import AdminCommands
AdminCommands().create_admin()
self.lresult = 1 # Indicate successful login
self.lusername = username

View File

@@ -66,7 +66,7 @@ log.add(
rotation="1 day",
retention="1 month",
)
log.critical("UI started")
valid_input = (0, 0, 0, 0, 0, 0)
@@ -1812,7 +1812,11 @@ def launch_gui():
# #log.debug("checking if database available")
log.info("Starting login dialog")
app = QtWidgets.QApplication(sys.argv)
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
else:
log.info("Using existing QApplication instance")
login_dialog = QtWidgets.QDialog()
ui = LoginDialog()
ui.setupUi(login_dialog)

View File

@@ -10,6 +10,7 @@ from PySide6.QtGui import QPainter, QPen, QColor
from PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis, QCategoryAxis
from src import LOG_DIR
from src.backend.semester import Semester
log = loguru.logger
log.remove()
@@ -37,7 +38,7 @@ class DataQtGraph(QtWidgets.QWidget):
def __init__(
self,
title: str,
data: dict,
data: dict[str, Union[list[str], dict[str, list[int]]]],
generateMissing: bool,
y_label: str,
x_rotation: int = 90,
@@ -53,16 +54,46 @@ class DataQtGraph(QtWidgets.QWidget):
lst = []
if generateMissing:
s_start = Semester.from_string(data["x"][0])
s_end = Semester.from_string(data["x"][-1])
# generate all semesters from start to end
missing_semesters = Semester.generate_missing(s_start, s_end)
x_data = data["x"]
y_data = data["y"]
if not isinstance(y_data, list):
for key in y_data:
data = {"x": x_data, "y": y_data[key]}
data = self.generateMissingSemesters(data)
data = {"x": [], "y": []}
data["y-label"] = key
for semester in missing_semesters:
if semester not in x_data:
data["x"].append(semester)
data["y"].append(0)
data["x"].append(semester)
# get the index of the semester in x_data
if semester in x_data:
index = x_data.index(semester)
print("index:", index)
print(key, y_data[key])
data["y"].append(y_data[key][index])
lst.append(data)
# for key in y_data:
# data = {"x": x_data, "y": y_data[key]}
# data = self.generateMissingSemesters(data)
# data["y-label"] = key
else:
data = self.generateMissingSemesters(data)
# data = self.generateMissingSemesters(data)
data = {"x": [], "y": []}
for semester in missing_semesters:
# if semester not in x_data, set y to 0
if semester not in x_data:
data["x"].append(semester)
data["y"].append(0)
data["x"].append(semester)
# get the index of the semester in x_data
if semester in x_data:
index = x_data.index(semester)
data["y"].append(y_data[index])
data["y-label"] = y_label
lst.append(data)
else:
@@ -76,9 +107,6 @@ class DataQtGraph(QtWidgets.QWidget):
else:
lst.append(data)
x_data = lst[0]["x"] #
xdict = dict(enumerate(x_data))
print("xdict:", xdict)
self.chart.createDefaultAxes()
for entry in lst:
@@ -88,6 +116,16 @@ class DataQtGraph(QtWidgets.QWidget):
#
entryseries.append(entry["x"].index(x_val), y_val)
entryseries.setName(entry["y-label"] if "y-label" in entry else y_label)
entryseries.setPen(
QPen(
QColor(
random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255),
),
2,
)
)
self.chart.addSeries(entryseries)
@@ -106,7 +144,7 @@ class DataQtGraph(QtWidgets.QWidget):
# str()
# )
self.chart.legend().setVisible(True)
self.chart.legend().setAlignment(QtCore.Qt.AlignmentFlag.AlignBottom)
self.chart.legend().setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
# set legend labels
self.chart.setAxisY(QValueAxis(self.chart), entryseries)

View File

@@ -1,14 +1,25 @@
from typing import Any
from .widget_sources.welcome_wizard_ui import Ui_Wizard
from PySide6 import QtWidgets, QtCore, QtGui
from src import settings
from src.backend import AdminCommands
from src import settings, LOG_DIR
from src.backend import Database
import sys
from appdirs import AppDirs
from pathlib import Path
import loguru
appdirs = AppDirs("SemesterApparatsManager", "SAM")
log = loguru.logger
log.remove()
log.add(sys.stdout, level="INFO")
log.add(f"{LOG_DIR}/application.log", rotation="1 MB", retention="10 days")
class WelcomeWizard(QtWidgets.QWizard, Ui_Wizard):
def __init__(self, parent=None):
super().__init__(parent)
log.info("Initializing WelcomeWizard")
self.setupUi(self)
self.btn_database.clicked.connect(self.open_database_settings)
self.btn_temp.clicked.connect(self.open_temp_settings)
@@ -16,49 +27,102 @@ class WelcomeWizard(QtWidgets.QWizard, Ui_Wizard):
self.btn_create.clicked.connect(self.create_sam_user)
# mail password field
self.settings_mail_password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
self.settings_zotero_api_key.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
self.settings_openai_api_key.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
self.sam_password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
# allow user to toggle password visibility
self.settings_mail_password.setContextMenuPolicy(
QtCore.Qt.ContextMenuPolicy.CustomContextMenu
)
self.settings_zotero_api_key.setContextMenuPolicy(
QtCore.Qt.ContextMenuPolicy.CustomContextMenu
)
self.settings_openai_api_key.setContextMenuPolicy(
QtCore.Qt.ContextMenuPolicy.CustomContextMenu
)
self.sam_password.setContextMenuPolicy(
QtCore.Qt.ContextMenuPolicy.CustomContextMenu
)
self.settings_mail_password.customContextMenuRequested.connect(
self.toggle_password_visibility
lambda pos: self.toggle_password_visibility(
pos, self.settings_mail_password
)
)
self.settings_zotero_api_key.customContextMenuRequested.connect(
lambda pos: self.toggle_password_visibility(
pos, self.settings_zotero_api_key
)
)
self.settings_openai_api_key.customContextMenuRequested.connect(
lambda pos: self.toggle_password_visibility(
pos, self.settings_openai_api_key
)
)
self.sam_password.customContextMenuRequested.connect(
lambda pos: self.toggle_password_visibility(pos, self.sam_password)
)
# if button for next page is clicked, run function to store settings
self.button(QtWidgets.QWizard.WizardButton.FinishButton).clicked.connect(
self.button(QtWidgets.QWizard.WizardButton.NextButton).clicked.connect(
self.store_settings
)
self.settings_mail_use_user_name.toggled.connect(self.set_check_text)
# set initial values for checkbox, database
self.set_check_text(self.settings_mail_use_user_name.isChecked())
self.settings_database.setText(
str(settings.database.path) or str(appdirs.user_data_dir)
str(settings.database.path)
if settings.database.path is not None
else str(appdirs.user_data_dir)
)
self.settings_temp.setText(
str(settings.database.temp) or str(appdirs.user_cache_dir)
str(settings.database.temp)
if settings.database.temp is not None
else str(appdirs.user_cache_dir)
)
self.settings_database_name.setText("semesterapparate.db")
def test_login_data(self):
sam_users = AdminCommands().list_users()
from src.backend import AdminCommands
log.info("Testing login data for SAM user")
db_path = (
self.settings_database.text() + "/" + self.settings_database_name.text()
)
db_path = Path(db_path).expanduser()
db = Database(db_path=db_path)
db.overwritePath(db_path)
db.initializeDatabase()
sam_users = AdminCommands(db_path=db_path).list_users()
sam_users = [user[2] for user in sam_users]
if not sam_users:
QtWidgets.QMessageBox.critical(
self,
"Error",
"No SAM users found. Please create a SAM user first.",
)
return
username = self.sam_username.text()
if username in sam_users:
QtWidgets.QMessageBox.information(
self,
"Error",
"Information",
f"User '{username}' exists in SAM.",
)
else:
QtWidgets.QMessageBox.information(
self,
"Information",
f"User '{username}' does not exist in SAM.",
)
def create_sam_user(self):
"""Create a SAM user in the database."""
admin = AdminCommands()
from src.backend import AdminCommands
db_path = (
self.settings_database.text() + "/" + self.settings_database_name.text()
)
db_path = Path(db_path).expanduser()
db = Database(db_path=db_path)
db.overwritePath(db_path)
db.initializeDatabase()
admin = AdminCommands(db_path=db_path)
admin.create_admin()
if not admin.create_user(self.sam_username.text(), self.sam_password.text()):
QtWidgets.QMessageBox.critical(
self,
@@ -79,17 +143,12 @@ class WelcomeWizard(QtWidgets.QWizard, Ui_Wizard):
else:
self.settings_mail_use_user_name.setText("Nutzername wird nicht verwendet")
def toggle_password_visibility(self, pos):
def toggle_password_visibility(self, pos: Any, field):
"""Toggle the visibility of the password field."""
if (
self.settings_mail_password.echoMode()
== QtWidgets.QLineEdit.EchoMode.Password
):
self.settings_mail_password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Normal)
if field.echoMode() == QtWidgets.QLineEdit.EchoMode.Password:
field.setEchoMode(QtWidgets.QLineEdit.EchoMode.Normal)
else:
self.settings_mail_password.setEchoMode(
QtWidgets.QLineEdit.EchoMode.Password
)
field.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
def store_settings(self):
# database page
@@ -135,7 +194,6 @@ class WelcomeWizard(QtWidgets.QWizard, Ui_Wizard):
settings.set_openai_attr("model", openai_model)
# save settings to file
print("Saving settings...")
print(settings)
settings.save()
def open_database_settings(self):

View File

@@ -23,7 +23,7 @@
<enum>Qt::PlainText</enum>
</property>
<property name="currentId">
<number>5</number>
<number>1</number>
</property>
<widget class="QWizardPage" name="wizardPage1">
<property name="title">
@@ -78,7 +78,7 @@ li.checked::marker { content: &quot;\2612&quot;; }
<string>Datenbank</string>
</property>
<property name="subTitle">
<string>Hier werden die Einstellungen für die Datenbank und temporären Dateien festgelegt. Über den [...] Knopf können die Datenbank und der Speicherort für die temporären Daten festgelegt werden</string>
<string>Hier werden die Einstellungen für die Datenbank und temporären Dateien festgelegt. Über den [...] Knopf können die Speicherordner ausgewählt werden.</string>
</property>
<attribute name="pageId">
<string notr="true">1</string>

View File

@@ -1,187 +1,245 @@
# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\widgets\widget_sources\welcome_wizard.ui'
#
# Created by: PySide6 UI code generator 6.9.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'welcome_wizard.ui'
##
## Created by: Qt User Interface Compiler version 6.9.1
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6 import QtCore, QtGui, QtWidgets
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QFormLayout,
QGridLayout, QHBoxLayout, QLabel, QLineEdit,
QPushButton, QSizePolicy, QSpacerItem, QTextEdit,
QToolButton, QVBoxLayout, QWidget, QWizard,
QWizardPage)
class Ui_Wizard(object):
def setupUi(self, Wizard):
Wizard.setObjectName("Wizard")
if not Wizard.objectName():
Wizard.setObjectName(u"Wizard")
Wizard.resize(564, 425)
Wizard.setSizeGripEnabled(False)
Wizard.setWizardStyle(QtWidgets.QWizard.WizardStyle.ClassicStyle)
Wizard.setSubTitleFormat(QtCore.Qt.TextFormat.PlainText)
Wizard.setCurrentId(5)
self.wizardPage1 = QtWidgets.QWizardPage()
self.wizardPage1.setSubTitle("")
self.wizardPage1.setObjectName("wizardPage1")
self.verticalLayout = QtWidgets.QVBoxLayout(self.wizardPage1)
self.verticalLayout.setObjectName("verticalLayout")
self.textEdit = QtWidgets.QTextEdit(parent=self.wizardPage1)
Wizard.setWizardStyle(QWizard.ClassicStyle)
Wizard.setSubTitleFormat(Qt.PlainText)
Wizard.setCurrentId(1)
self.wizardPage1 = QWizardPage()
self.wizardPage1.setObjectName(u"wizardPage1")
self.verticalLayout = QVBoxLayout(self.wizardPage1)
self.verticalLayout.setObjectName(u"verticalLayout")
self.textEdit = QTextEdit(self.wizardPage1)
self.textEdit.setObjectName(u"textEdit")
self.textEdit.setEnabled(False)
self.textEdit.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
self.textEdit.setFocusPolicy(Qt.NoFocus)
self.textEdit.setLineWidth(0)
self.textEdit.setAutoFormatting(QtWidgets.QTextEdit.AutoFormattingFlag.AutoAll)
self.textEdit.setAutoFormatting(QTextEdit.AutoAll)
self.textEdit.setReadOnly(True)
self.textEdit.setObjectName("textEdit")
self.verticalLayout.addWidget(self.textEdit)
Wizard.addPage(self.wizardPage1)
self.wizardPage2 = QtWidgets.QWizardPage()
self.wizardPage2.setObjectName("wizardPage2")
self.gridLayout = QtWidgets.QGridLayout(self.wizardPage2)
self.gridLayout.setObjectName("gridLayout")
self.settings_temp = QtWidgets.QLineEdit(parent=self.wizardPage2)
self.settings_temp.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
Wizard.setPage(0, self.wizardPage1)
self.wizardPage2 = QWizardPage()
self.wizardPage2.setObjectName(u"wizardPage2")
self.gridLayout = QGridLayout(self.wizardPage2)
self.gridLayout.setObjectName(u"gridLayout")
self.settings_temp = QLineEdit(self.wizardPage2)
self.settings_temp.setObjectName(u"settings_temp")
self.settings_temp.setFocusPolicy(Qt.NoFocus)
self.settings_temp.setReadOnly(True)
self.settings_temp.setObjectName("settings_temp")
self.gridLayout.addWidget(self.settings_temp, 2, 1, 1, 1)
self.label = QtWidgets.QLabel(parent=self.wizardPage2)
self.label.setObjectName("label")
self.label = QLabel(self.wizardPage2)
self.label.setObjectName(u"label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.settings_database = QtWidgets.QLineEdit(parent=self.wizardPage2)
self.settings_database.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
self.settings_database = QLineEdit(self.wizardPage2)
self.settings_database.setObjectName(u"settings_database")
self.settings_database.setFocusPolicy(Qt.NoFocus)
self.settings_database.setReadOnly(True)
self.settings_database.setPlaceholderText("")
self.settings_database.setObjectName("settings_database")
self.gridLayout.addWidget(self.settings_database, 0, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(parent=self.wizardPage2)
self.label_2.setObjectName("label_2")
self.label_2 = QLabel(self.wizardPage2)
self.label_2.setObjectName(u"label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.btn_database = QtWidgets.QToolButton(parent=self.wizardPage2)
self.btn_database.setObjectName("btn_database")
self.btn_database = QToolButton(self.wizardPage2)
self.btn_database.setObjectName(u"btn_database")
self.gridLayout.addWidget(self.btn_database, 0, 2, 1, 1)
self.btn_temp = QtWidgets.QToolButton(parent=self.wizardPage2)
self.btn_temp.setObjectName("btn_temp")
self.btn_temp = QToolButton(self.wizardPage2)
self.btn_temp.setObjectName(u"btn_temp")
self.gridLayout.addWidget(self.btn_temp, 2, 2, 1, 1)
self.label_16 = QtWidgets.QLabel(parent=self.wizardPage2)
self.label_16.setObjectName("label_16")
self.label_16 = QLabel(self.wizardPage2)
self.label_16.setObjectName(u"label_16")
self.gridLayout.addWidget(self.label_16, 1, 0, 1, 1)
self.settings_database_name = QtWidgets.QLineEdit(parent=self.wizardPage2)
self.settings_database_name.setObjectName("settings_database_name")
self.settings_database_name = QLineEdit(self.wizardPage2)
self.settings_database_name.setObjectName(u"settings_database_name")
self.gridLayout.addWidget(self.settings_database_name, 1, 1, 1, 1)
Wizard.addPage(self.wizardPage2)
self.wizardPage3 = QtWidgets.QWizardPage()
self.wizardPage3.setObjectName("wizardPage3")
self.formLayout = QtWidgets.QFormLayout(self.wizardPage3)
self.formLayout.setObjectName("formLayout")
self.label_3 = QtWidgets.QLabel(parent=self.wizardPage3)
self.label_3.setObjectName("label_3")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_3)
self.settings_mail_smtp_server = QtWidgets.QLineEdit(parent=self.wizardPage3)
Wizard.setPage(1, self.wizardPage2)
self.wizardPage3 = QWizardPage()
self.wizardPage3.setObjectName(u"wizardPage3")
self.formLayout = QFormLayout(self.wizardPage3)
self.formLayout.setObjectName(u"formLayout")
self.label_3 = QLabel(self.wizardPage3)
self.label_3.setObjectName(u"label_3")
self.formLayout.setWidget(0, QFormLayout.ItemRole.LabelRole, self.label_3)
self.settings_mail_smtp_server = QLineEdit(self.wizardPage3)
self.settings_mail_smtp_server.setObjectName(u"settings_mail_smtp_server")
self.settings_mail_smtp_server.setClearButtonEnabled(True)
self.settings_mail_smtp_server.setObjectName("settings_mail_smtp_server")
self.formLayout.setWidget(
0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_mail_smtp_server
)
self.settings_mail_smtp_port = QtWidgets.QLineEdit(parent=self.wizardPage3)
self.settings_mail_smtp_port.setInputMethodHints(
QtCore.Qt.InputMethodHint.ImhDigitsOnly
)
self.formLayout.setWidget(0, QFormLayout.ItemRole.FieldRole, self.settings_mail_smtp_server)
self.settings_mail_smtp_port = QLineEdit(self.wizardPage3)
self.settings_mail_smtp_port.setObjectName(u"settings_mail_smtp_port")
self.settings_mail_smtp_port.setInputMethodHints(Qt.ImhDigitsOnly)
self.settings_mail_smtp_port.setClearButtonEnabled(True)
self.settings_mail_smtp_port.setObjectName("settings_mail_smtp_port")
self.formLayout.setWidget(
1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_mail_smtp_port
)
self.settings_mail_user_name = QtWidgets.QLineEdit(parent=self.wizardPage3)
self.formLayout.setWidget(1, QFormLayout.ItemRole.FieldRole, self.settings_mail_smtp_port)
self.settings_mail_user_name = QLineEdit(self.wizardPage3)
self.settings_mail_user_name.setObjectName(u"settings_mail_user_name")
self.settings_mail_user_name.setClearButtonEnabled(True)
self.settings_mail_user_name.setObjectName("settings_mail_user_name")
self.formLayout.setWidget(
3, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_mail_user_name
)
self.settings_mail_password = QtWidgets.QLineEdit(parent=self.wizardPage3)
self.settings_mail_password.setStatusTip("")
self.settings_mail_password.setWhatsThis("")
self.settings_mail_password.setObjectName("settings_mail_password")
self.formLayout.setWidget(
4, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_mail_password
)
self.label_4 = QtWidgets.QLabel(parent=self.wizardPage3)
self.label_4.setObjectName("label_4")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_4)
self.label_5 = QtWidgets.QLabel(parent=self.wizardPage3)
self.label_5.setObjectName("label_5")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_5)
self.label_6 = QtWidgets.QLabel(parent=self.wizardPage3)
self.label_6.setObjectName("label_6")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_6)
self.settings_mail_use_user_name = QtWidgets.QCheckBox(parent=self.wizardPage3)
self.settings_mail_use_user_name.setObjectName("settings_mail_use_user_name")
self.formLayout.setWidget(8, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_mail_use_user_name)
self.settings_mail_printer = QtWidgets.QLineEdit(parent=self.wizardPage3)
self.formLayout.setWidget(3, QFormLayout.ItemRole.FieldRole, self.settings_mail_user_name)
self.settings_mail_password = QLineEdit(self.wizardPage3)
self.settings_mail_password.setObjectName(u"settings_mail_password")
self.formLayout.setWidget(4, QFormLayout.ItemRole.FieldRole, self.settings_mail_password)
self.label_4 = QLabel(self.wizardPage3)
self.label_4.setObjectName(u"label_4")
self.formLayout.setWidget(3, QFormLayout.ItemRole.LabelRole, self.label_4)
self.label_5 = QLabel(self.wizardPage3)
self.label_5.setObjectName(u"label_5")
self.formLayout.setWidget(1, QFormLayout.ItemRole.LabelRole, self.label_5)
self.label_6 = QLabel(self.wizardPage3)
self.label_6.setObjectName(u"label_6")
self.formLayout.setWidget(4, QFormLayout.ItemRole.LabelRole, self.label_6)
self.settings_mail_use_user_name = QCheckBox(self.wizardPage3)
self.settings_mail_use_user_name.setObjectName(u"settings_mail_use_user_name")
self.formLayout.setWidget(8, QFormLayout.ItemRole.FieldRole, self.settings_mail_use_user_name)
self.settings_mail_printer = QLineEdit(self.wizardPage3)
self.settings_mail_printer.setObjectName(u"settings_mail_printer")
self.settings_mail_printer.setClearButtonEnabled(True)
self.settings_mail_printer.setObjectName("settings_mail_printer")
self.formLayout.setWidget(
7, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_mail_printer
)
self.label_8 = QtWidgets.QLabel(parent=self.wizardPage3)
self.label_8.setObjectName("label_8")
self.formLayout.setWidget(7, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_8)
self.label_9 = QtWidgets.QLabel(parent=self.wizardPage3)
self.label_9.setObjectName("label_9")
self.formLayout.setWidget(8, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_9)
self.settings_mail_signature = QtWidgets.QTextEdit(parent=self.wizardPage3)
self.settings_mail_signature.setObjectName("settings_mail_signature")
self.formLayout.setWidget(
5, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_mail_signature
)
self.label_10 = QtWidgets.QLabel(parent=self.wizardPage3)
self.label_10.setObjectName("label_10")
self.formLayout.setWidget(5, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_10)
self.label_7 = QtWidgets.QLabel(parent=self.wizardPage3)
self.label_7.setObjectName("label_7")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_7)
self.settings_mail_address = QtWidgets.QLineEdit(parent=self.wizardPage3)
self.formLayout.setWidget(7, QFormLayout.ItemRole.FieldRole, self.settings_mail_printer)
self.label_8 = QLabel(self.wizardPage3)
self.label_8.setObjectName(u"label_8")
self.formLayout.setWidget(7, QFormLayout.ItemRole.LabelRole, self.label_8)
self.label_9 = QLabel(self.wizardPage3)
self.label_9.setObjectName(u"label_9")
self.formLayout.setWidget(8, QFormLayout.ItemRole.LabelRole, self.label_9)
self.settings_mail_signature = QTextEdit(self.wizardPage3)
self.settings_mail_signature.setObjectName(u"settings_mail_signature")
self.formLayout.setWidget(5, QFormLayout.ItemRole.FieldRole, self.settings_mail_signature)
self.label_10 = QLabel(self.wizardPage3)
self.label_10.setObjectName(u"label_10")
self.formLayout.setWidget(5, QFormLayout.ItemRole.LabelRole, self.label_10)
self.label_7 = QLabel(self.wizardPage3)
self.label_7.setObjectName(u"label_7")
self.formLayout.setWidget(2, QFormLayout.ItemRole.LabelRole, self.label_7)
self.settings_mail_address = QLineEdit(self.wizardPage3)
self.settings_mail_address.setObjectName(u"settings_mail_address")
self.settings_mail_address.setClearButtonEnabled(True)
self.settings_mail_address.setObjectName("settings_mail_address")
self.formLayout.setWidget(
2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_mail_address
)
Wizard.addPage(self.wizardPage3)
self.wizardPage4 = QtWidgets.QWizardPage()
self.wizardPage4.setObjectName("wizardPage4")
self.formLayout_2 = QtWidgets.QFormLayout(self.wizardPage4)
self.formLayout_2.setObjectName("formLayout_2")
self.label_11 = QtWidgets.QLabel(parent=self.wizardPage4)
self.label_11.setObjectName("label_11")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_11)
self.settings_zotero_api_key = QtWidgets.QLineEdit(parent=self.wizardPage4)
self.settings_zotero_api_key.setObjectName("settings_zotero_api_key")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_zotero_api_key)
self.settings_zotero_library_id = QtWidgets.QLineEdit(parent=self.wizardPage4)
self.settings_zotero_library_id.setObjectName("settings_zotero_library_id")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_zotero_library_id)
self.label_12 = QtWidgets.QLabel(parent=self.wizardPage4)
self.label_12.setObjectName("label_12")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_12)
self.label_13 = QtWidgets.QLabel(parent=self.wizardPage4)
self.label_13.setObjectName("label_13")
self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_13)
self.settings_zotero_library_type = QtWidgets.QLineEdit(parent=self.wizardPage4)
self.settings_zotero_library_type.setObjectName("settings_zotero_library_type")
self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_zotero_library_type)
Wizard.addPage(self.wizardPage4)
self.wizardPage5 = QtWidgets.QWizardPage()
self.wizardPage5.setObjectName("wizardPage5")
self.formLayout_3 = QtWidgets.QFormLayout(self.wizardPage5)
self.formLayout_3.setObjectName("formLayout_3")
self.settings_openai_api_key = QtWidgets.QLineEdit(parent=self.wizardPage5)
self.settings_openai_api_key.setObjectName("settings_openai_api_key")
self.formLayout_3.setWidget(
0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_openai_api_key
)
self.label_14 = QtWidgets.QLabel(parent=self.wizardPage5)
self.label_14.setObjectName("label_14")
self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_14)
self.label_15 = QtWidgets.QLabel(parent=self.wizardPage5)
self.label_15.setObjectName("label_15")
self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_15)
self.settings_openai_model = QtWidgets.QComboBox(parent=self.wizardPage5)
self.settings_openai_model.setObjectName("settings_openai_model")
self.formLayout.setWidget(2, QFormLayout.ItemRole.FieldRole, self.settings_mail_address)
Wizard.setPage(2, self.wizardPage3)
self.wizardPage4 = QWizardPage()
self.wizardPage4.setObjectName(u"wizardPage4")
self.formLayout_2 = QFormLayout(self.wizardPage4)
self.formLayout_2.setObjectName(u"formLayout_2")
self.label_11 = QLabel(self.wizardPage4)
self.label_11.setObjectName(u"label_11")
self.formLayout_2.setWidget(0, QFormLayout.ItemRole.LabelRole, self.label_11)
self.settings_zotero_api_key = QLineEdit(self.wizardPage4)
self.settings_zotero_api_key.setObjectName(u"settings_zotero_api_key")
self.formLayout_2.setWidget(0, QFormLayout.ItemRole.FieldRole, self.settings_zotero_api_key)
self.settings_zotero_library_id = QLineEdit(self.wizardPage4)
self.settings_zotero_library_id.setObjectName(u"settings_zotero_library_id")
self.formLayout_2.setWidget(1, QFormLayout.ItemRole.FieldRole, self.settings_zotero_library_id)
self.label_12 = QLabel(self.wizardPage4)
self.label_12.setObjectName(u"label_12")
self.formLayout_2.setWidget(1, QFormLayout.ItemRole.LabelRole, self.label_12)
self.label_13 = QLabel(self.wizardPage4)
self.label_13.setObjectName(u"label_13")
self.formLayout_2.setWidget(2, QFormLayout.ItemRole.LabelRole, self.label_13)
self.settings_zotero_library_type = QLineEdit(self.wizardPage4)
self.settings_zotero_library_type.setObjectName(u"settings_zotero_library_type")
self.formLayout_2.setWidget(2, QFormLayout.ItemRole.FieldRole, self.settings_zotero_library_type)
Wizard.setPage(3, self.wizardPage4)
self.wizardPage5 = QWizardPage()
self.wizardPage5.setObjectName(u"wizardPage5")
self.formLayout_3 = QFormLayout(self.wizardPage5)
self.formLayout_3.setObjectName(u"formLayout_3")
self.settings_openai_api_key = QLineEdit(self.wizardPage5)
self.settings_openai_api_key.setObjectName(u"settings_openai_api_key")
self.formLayout_3.setWidget(0, QFormLayout.ItemRole.FieldRole, self.settings_openai_api_key)
self.label_14 = QLabel(self.wizardPage5)
self.label_14.setObjectName(u"label_14")
self.formLayout_3.setWidget(0, QFormLayout.ItemRole.LabelRole, self.label_14)
self.label_15 = QLabel(self.wizardPage5)
self.label_15.setObjectName(u"label_15")
self.formLayout_3.setWidget(1, QFormLayout.ItemRole.LabelRole, self.label_15)
self.settings_openai_model = QComboBox(self.wizardPage5)
self.settings_openai_model.addItem("")
self.settings_openai_model.addItem("")
self.settings_openai_model.addItem("")
@@ -189,163 +247,156 @@ class Ui_Wizard(object):
self.settings_openai_model.addItem("")
self.settings_openai_model.addItem("")
self.settings_openai_model.addItem("")
self.formLayout_3.setWidget(
1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.settings_openai_model
)
Wizard.addPage(self.wizardPage5)
self.wizardPage6 = QtWidgets.QWizardPage()
self.wizardPage6.setObjectName("wizardPage6")
self.formLayout_4 = QtWidgets.QFormLayout(self.wizardPage6)
self.formLayout_4.setObjectName("formLayout_4")
self.label_17 = QtWidgets.QLabel(parent=self.wizardPage6)
self.label_17.setObjectName("label_17")
self.formLayout_4.setWidget(
0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_17
)
self.sam_username = QtWidgets.QLineEdit(parent=self.wizardPage6)
self.sam_username.setObjectName("sam_username")
self.formLayout_4.setWidget(
0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.sam_username
)
self.label_18 = QtWidgets.QLabel(parent=self.wizardPage6)
self.label_18.setObjectName("label_18")
self.formLayout_4.setWidget(
1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_18
)
self.sam_password = QtWidgets.QLineEdit(parent=self.wizardPage6)
self.sam_password.setObjectName("sam_password")
self.formLayout_4.setWidget(
1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.sam_password
)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.btn_test = QtWidgets.QPushButton(parent=self.wizardPage6)
self.btn_test.setObjectName("btn_test")
self.settings_openai_model.setObjectName(u"settings_openai_model")
self.formLayout_3.setWidget(1, QFormLayout.ItemRole.FieldRole, self.settings_openai_model)
Wizard.setPage(9, self.wizardPage5)
self.wizardPage6 = QWizardPage()
self.wizardPage6.setObjectName(u"wizardPage6")
self.formLayout_4 = QFormLayout(self.wizardPage6)
self.formLayout_4.setObjectName(u"formLayout_4")
self.label_17 = QLabel(self.wizardPage6)
self.label_17.setObjectName(u"label_17")
self.formLayout_4.setWidget(0, QFormLayout.ItemRole.LabelRole, self.label_17)
self.sam_username = QLineEdit(self.wizardPage6)
self.sam_username.setObjectName(u"sam_username")
self.formLayout_4.setWidget(0, QFormLayout.ItemRole.FieldRole, self.sam_username)
self.label_18 = QLabel(self.wizardPage6)
self.label_18.setObjectName(u"label_18")
self.formLayout_4.setWidget(1, QFormLayout.ItemRole.LabelRole, self.label_18)
self.sam_password = QLineEdit(self.wizardPage6)
self.sam_password.setObjectName(u"sam_password")
self.formLayout_4.setWidget(1, QFormLayout.ItemRole.FieldRole, self.sam_password)
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.btn_test = QPushButton(self.wizardPage6)
self.btn_test.setObjectName(u"btn_test")
self.horizontalLayout.addWidget(self.btn_test)
self.btn_create = QtWidgets.QPushButton(parent=self.wizardPage6)
self.btn_create.setDefault(True)
self.btn_create = QPushButton(self.wizardPage6)
self.btn_create.setObjectName(u"btn_create")
self.btn_create.setFlat(False)
self.btn_create.setObjectName("btn_create")
self.horizontalLayout.addWidget(self.btn_create)
self.formLayout_4.setLayout(
2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.horizontalLayout
)
spacerItem = QtWidgets.QSpacerItem(
20,
40,
QtWidgets.QSizePolicy.Policy.Minimum,
QtWidgets.QSizePolicy.Policy.Expanding,
)
self.formLayout_4.setItem(
3, QtWidgets.QFormLayout.ItemRole.FieldRole, spacerItem
)
self.formLayout_4.setLayout(2, QFormLayout.ItemRole.FieldRole, self.horizontalLayout)
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.formLayout_4.setItem(3, QFormLayout.ItemRole.FieldRole, self.verticalSpacer)
Wizard.addPage(self.wizardPage6)
QWidget.setTabOrder(self.settings_database, self.btn_database)
QWidget.setTabOrder(self.btn_database, self.settings_database_name)
QWidget.setTabOrder(self.settings_database_name, self.settings_temp)
QWidget.setTabOrder(self.settings_temp, self.btn_temp)
QWidget.setTabOrder(self.btn_temp, self.settings_mail_smtp_server)
QWidget.setTabOrder(self.settings_mail_smtp_server, self.settings_mail_smtp_port)
QWidget.setTabOrder(self.settings_mail_smtp_port, self.settings_mail_address)
QWidget.setTabOrder(self.settings_mail_address, self.settings_mail_user_name)
QWidget.setTabOrder(self.settings_mail_user_name, self.settings_mail_password)
QWidget.setTabOrder(self.settings_mail_password, self.settings_mail_signature)
QWidget.setTabOrder(self.settings_mail_signature, self.settings_mail_printer)
QWidget.setTabOrder(self.settings_mail_printer, self.settings_mail_use_user_name)
QWidget.setTabOrder(self.settings_mail_use_user_name, self.settings_zotero_api_key)
QWidget.setTabOrder(self.settings_zotero_api_key, self.settings_zotero_library_id)
QWidget.setTabOrder(self.settings_zotero_library_id, self.settings_zotero_library_type)
QWidget.setTabOrder(self.settings_zotero_library_type, self.settings_openai_api_key)
QWidget.setTabOrder(self.settings_openai_api_key, self.settings_openai_model)
self.retranslateUi(Wizard)
QtCore.QMetaObject.connectSlotsByName(Wizard)
Wizard.setTabOrder(self.settings_database, self.btn_database)
Wizard.setTabOrder(self.btn_database, self.settings_database_name)
Wizard.setTabOrder(self.settings_database_name, self.settings_temp)
Wizard.setTabOrder(self.settings_temp, self.btn_temp)
Wizard.setTabOrder(self.btn_temp, self.settings_mail_smtp_server)
Wizard.setTabOrder(self.settings_mail_smtp_server, self.settings_mail_smtp_port)
Wizard.setTabOrder(self.settings_mail_smtp_port, self.settings_mail_address)
Wizard.setTabOrder(self.settings_mail_address, self.settings_mail_user_name)
Wizard.setTabOrder(self.settings_mail_user_name, self.settings_mail_password)
Wizard.setTabOrder(self.settings_mail_password, self.settings_mail_signature)
Wizard.setTabOrder(self.settings_mail_signature, self.settings_mail_printer)
Wizard.setTabOrder(self.settings_mail_printer, self.settings_mail_use_user_name)
Wizard.setTabOrder(
self.settings_mail_use_user_name, self.settings_zotero_api_key
)
Wizard.setTabOrder(
self.settings_zotero_api_key, self.settings_zotero_library_id
)
Wizard.setTabOrder(
self.settings_zotero_library_id, self.settings_zotero_library_type
)
Wizard.setTabOrder(
self.settings_zotero_library_type, self.settings_openai_api_key
)
Wizard.setTabOrder(self.settings_openai_api_key, self.settings_openai_model)
self.btn_create.setDefault(True)
QMetaObject.connectSlotsByName(Wizard)
# setupUi
def retranslateUi(self, Wizard):
_translate = QtCore.QCoreApplication.translate
Wizard.setWindowTitle(_translate("Wizard", "Wizard"))
self.wizardPage1.setTitle(_translate("Wizard", "Willkommen"))
self.textEdit.setHtml(
_translate(
"Wizard",
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">\n'
'<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">\n'
"p, li { white-space: pre-wrap; }\n"
"hr { height: 1px; border-width: 0; }\n"
'li.unchecked::marker { content: "\\2610"; }\n'
'li.checked::marker { content: "\\2612"; }\n'
"</style></head><body style=\" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Es wurde erkannt, dass der SemesterApparatsManager (SAM) zum ersten Mal gestartet wurde. In den Folgenden Seiten werden die grundlegenden Einstellungen festgelegt, anschließend wird SAM geöffnet. Folgende Einstellungen werden über diesen Wizard festgelegt:</p>\n'
'<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>\n'
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- Datenbank</p>\n'
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- eMail</p>\n'
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- Zotero Integration</p>\n'
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- KI Integration</p>\n'
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Anschließend kann ein Nutzeraccount für SAM erstellt werden</p></body></html>',
)
)
self.wizardPage2.setTitle(_translate("Wizard", "Datenbank"))
self.wizardPage2.setSubTitle(
_translate(
"Wizard",
"Hier werden die Einstellungen für die Datenbank und temporären Dateien festgelegt. Über den [...] Knopf können die Datenbank und der Speicherort für die temporären Daten festgelegt werden",
)
)
self.settings_temp.setPlaceholderText(_translate("Wizard", "C:\\Users\\[Nutzer]\\AppData\\Local\\SAM\\SemesterApparatsManager\\Cache"))
self.label.setText(_translate("Wizard", "Datenbankpfad"))
self.label_2.setText(_translate("Wizard", "Temporäre Daten"))
self.btn_database.setText(_translate("Wizard", "..."))
self.btn_temp.setText(_translate("Wizard", "..."))
self.label_16.setText(_translate("Wizard", "Datenbankname"))
self.settings_database_name.setPlaceholderText(
_translate("Wizard", "semesterapparate.db")
)
self.wizardPage3.setTitle(_translate("Wizard", "Mail"))
self.wizardPage3.setSubTitle(_translate("Wizard", "Hier werden die Einstellungen für die Mailverbindung eingegeben"))
self.label_3.setText(_translate("Wizard", "SMTP Server"))
self.settings_mail_password.setToolTip(
_translate("Wizard", "Rechtsklick, um passwort anzuzeigen")
)
self.label_4.setText(_translate("Wizard", "Nutzername"))
self.label_5.setText(_translate("Wizard", "SMTP Port"))
self.label_6.setText(_translate("Wizard", "Passwort"))
self.settings_mail_use_user_name.setText(_translate("Wizard", "CheckBox"))
self.label_8.setText(_translate("Wizard", "Druckermail"))
self.label_9.setText(_translate("Wizard", "Nutzername\n"
"für SMTP"))
self.label_10.setText(_translate("Wizard", "Signatur"))
self.label_7.setText(_translate("Wizard", "Mail Adresse"))
self.wizardPage4.setTitle(_translate("Wizard", "Zotero"))
self.wizardPage4.setSubTitle(_translate("Wizard", "Hier werden die Einstellungen für Zotero verwaltet"))
self.label_11.setText(_translate("Wizard", "API-Key"))
self.label_12.setText(_translate("Wizard", "ID"))
self.label_13.setText(_translate("Wizard", "Anwendungstyp"))
self.settings_zotero_library_type.setText(_translate("Wizard", "user"))
self.wizardPage5.setTitle(_translate("Wizard", "KI-Integration"))
self.wizardPage5.setSubTitle(_translate("Wizard", "Hier werden die Einstellungen für die KI Integration eingestellt."))
self.label_14.setText(_translate("Wizard", "API Key"))
self.label_15.setText(_translate("Wizard", "ChatGPT Modell"))
self.settings_openai_model.setCurrentText(_translate("Wizard", "gpt3.5-turbo"))
self.settings_openai_model.setItemText(0, _translate("Wizard", "gpt3.5-turbo"))
self.settings_openai_model.setItemText(1, _translate("Wizard", "gpt-4"))
self.settings_openai_model.setItemText(2, _translate("Wizard", "gpt-4o"))
self.settings_openai_model.setItemText(3, _translate("Wizard", "gpt-4o-mini"))
self.settings_openai_model.setItemText(4, _translate("Wizard", "gpt-4.1"))
self.settings_openai_model.setItemText(5, _translate("Wizard", "gpt-4.1-mini"))
self.settings_openai_model.setItemText(6, _translate("Wizard", "gpt-4.1-nano"))
self.wizardPage6.setTitle(_translate("Wizard", "SAM Nutzer"))
self.wizardPage6.setSubTitle(
_translate("Wizard", "Hier kann ein Nutzer für SAM erstellt werden")
)
self.label_17.setText(_translate("Wizard", "Nutzername"))
self.label_18.setText(_translate("Wizard", "Passwort"))
self.btn_test.setText(_translate("Wizard", "Prüfen"))
self.btn_create.setText(_translate("Wizard", "Anlegen"))
Wizard.setWindowTitle(QCoreApplication.translate("Wizard", u"Wizard", None))
self.wizardPage1.setTitle(QCoreApplication.translate("Wizard", u"Willkommen", None))
self.wizardPage1.setSubTitle("")
self.textEdit.setHtml(QCoreApplication.translate("Wizard", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><meta charset=\"utf-8\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"hr { height: 1px; border-width: 0; }\n"
"li.unchecked::marker { content: \"\\2610\"; }\n"
"li.checked::marker { content: \"\\2612\"; }\n"
"</style></head><body style=\" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Es wurde erkannt, dass der SemesterApparatsManager (SAM) zum ersten Mal gestartet wurde. In den Folgenden Seiten werden die grundlegenden Einstellungen festgelegt, anschlie\u00dfend wird SAM ge\u00f6ffnet. Folgende Einstellungen werden \u00fcber diesen Wizard festgelegt:</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent"
":0; text-indent:0px;\"><br /></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">- Datenbank</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">- eMail</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">- Zotero Integration</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">- KI Integration</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Anschlie\u00dfend kann ein Nutzeraccount f\u00fcr SAM erstellt werden</p></body></html>", None))
self.wizardPage2.setTitle(QCoreApplication.translate("Wizard", u"Datenbank", None))
self.wizardPage2.setSubTitle(QCoreApplication.translate("Wizard", u"Hier werden die Einstellungen f\u00fcr die Datenbank und tempor\u00e4ren Dateien festgelegt. \u00dcber den [...] Knopf k\u00f6nnen die Speicherordner ausgew\u00e4hlt werden.", None))
self.settings_temp.setPlaceholderText(QCoreApplication.translate("Wizard", u"C:\\Users\\[Nutzer]\\AppData\\Local\\SAM\\SemesterApparatsManager\\Cache", None))
self.label.setText(QCoreApplication.translate("Wizard", u"Datenbankpfad", None))
self.settings_database.setPlaceholderText("")
self.label_2.setText(QCoreApplication.translate("Wizard", u"Tempor\u00e4re Daten", None))
self.btn_database.setText(QCoreApplication.translate("Wizard", u"...", None))
self.btn_temp.setText(QCoreApplication.translate("Wizard", u"...", None))
self.label_16.setText(QCoreApplication.translate("Wizard", u"Datenbankname", None))
self.settings_database_name.setPlaceholderText(QCoreApplication.translate("Wizard", u"semesterapparate.db", None))
self.wizardPage3.setTitle(QCoreApplication.translate("Wizard", u"Mail", None))
self.wizardPage3.setSubTitle(QCoreApplication.translate("Wizard", u"Hier werden die Einstellungen f\u00fcr die Mailverbindung eingegeben", None))
self.label_3.setText(QCoreApplication.translate("Wizard", u"SMTP Server", None))
#if QT_CONFIG(tooltip)
self.settings_mail_password.setToolTip(QCoreApplication.translate("Wizard", u"Rechtsklick, um passwort anzuzeigen", None))
#endif // QT_CONFIG(tooltip)
#if QT_CONFIG(statustip)
self.settings_mail_password.setStatusTip("")
#endif // QT_CONFIG(statustip)
#if QT_CONFIG(whatsthis)
self.settings_mail_password.setWhatsThis("")
#endif // QT_CONFIG(whatsthis)
self.label_4.setText(QCoreApplication.translate("Wizard", u"Nutzername", None))
self.label_5.setText(QCoreApplication.translate("Wizard", u"SMTP Port", None))
self.label_6.setText(QCoreApplication.translate("Wizard", u"Passwort", None))
self.settings_mail_use_user_name.setText(QCoreApplication.translate("Wizard", u"CheckBox", None))
self.label_8.setText(QCoreApplication.translate("Wizard", u"Druckermail", None))
self.label_9.setText(QCoreApplication.translate("Wizard", u"Nutzername\n"
"f\u00fcr SMTP", None))
self.label_10.setText(QCoreApplication.translate("Wizard", u"Signatur", None))
self.label_7.setText(QCoreApplication.translate("Wizard", u"Mail Adresse", None))
self.wizardPage4.setTitle(QCoreApplication.translate("Wizard", u"Zotero", None))
self.wizardPage4.setSubTitle(QCoreApplication.translate("Wizard", u"Hier werden die Einstellungen f\u00fcr Zotero verwaltet", None))
self.label_11.setText(QCoreApplication.translate("Wizard", u"API-Key", None))
self.label_12.setText(QCoreApplication.translate("Wizard", u"ID", None))
self.label_13.setText(QCoreApplication.translate("Wizard", u"Anwendungstyp", None))
self.settings_zotero_library_type.setText(QCoreApplication.translate("Wizard", u"user", None))
self.wizardPage5.setTitle(QCoreApplication.translate("Wizard", u"KI-Integration", None))
self.wizardPage5.setSubTitle(QCoreApplication.translate("Wizard", u"Hier werden die Einstellungen f\u00fcr die KI Integration eingestellt.", None))
self.label_14.setText(QCoreApplication.translate("Wizard", u"API Key", None))
self.label_15.setText(QCoreApplication.translate("Wizard", u"ChatGPT Modell", None))
self.settings_openai_model.setItemText(0, QCoreApplication.translate("Wizard", u"gpt3.5-turbo", None))
self.settings_openai_model.setItemText(1, QCoreApplication.translate("Wizard", u"gpt-4", None))
self.settings_openai_model.setItemText(2, QCoreApplication.translate("Wizard", u"gpt-4o", None))
self.settings_openai_model.setItemText(3, QCoreApplication.translate("Wizard", u"gpt-4o-mini", None))
self.settings_openai_model.setItemText(4, QCoreApplication.translate("Wizard", u"gpt-4.1", None))
self.settings_openai_model.setItemText(5, QCoreApplication.translate("Wizard", u"gpt-4.1-mini", None))
self.settings_openai_model.setItemText(6, QCoreApplication.translate("Wizard", u"gpt-4.1-nano", None))
self.settings_openai_model.setCurrentText(QCoreApplication.translate("Wizard", u"gpt3.5-turbo", None))
self.wizardPage6.setTitle(QCoreApplication.translate("Wizard", u"SAM Nutzer", None))
self.wizardPage6.setSubTitle(QCoreApplication.translate("Wizard", u"Hier kann ein Nutzer f\u00fcr SAM erstellt werden", None))
self.label_17.setText(QCoreApplication.translate("Wizard", u"Nutzername", None))
self.label_18.setText(QCoreApplication.translate("Wizard", u"Passwort", None))
self.btn_test.setText(QCoreApplication.translate("Wizard", u"Pr\u00fcfen", None))
self.btn_create.setText(QCoreApplication.translate("Wizard", u"Anlegen", None))
# retranslateUi