diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..f21d06e --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,62 @@ +on: + workflow_dispatch: + inputs: + release_notes: + description: Release notes (use \n for newlines) + type: string + required: false + github_release: + description: 'Create Gitea Release' + default: true + type: boolean + bump: + description: 'Bump type' + required: false + default: 'patch' + type: choice + options: + - 'major' + - 'minor' + - 'patch' + + +jobs: + bump: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install UV + uses: astral-sh/setup-uv@v5 + - name: Set up Python + run: uv python install + with: + python-version-file: "pyproject.toml" + - name: Install dependencies + run: uv sync --locked --all-extras --dev + - name: Install Bump tool + run: uv tool install bump-my-version + - name: Bump version + id: bump_version + run: | + uv tool run bump-my-version --bump ${{ github.event.inputs.bump }} --tag --allow-dirty + - name: Add release notes + id: add_release_notes + run: | + echo "RELEASE_NOTES<> $GITHUB_ENV + echo "${{ github.event.inputs.release_notes }}" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + - name: Create Gitea Release + if: ${{ github.event.inputs.github_release == 'true' }} + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ github.sha }} + release_name: Release ${{ github.sha }} + body: ${{ env.RELEASE_NOTES }} + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.TOKEN }} + GITHUB_REPOSITORY: ${{ github.repository }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 04a73a4..aecf6cf 100644 --- a/.gitignore +++ b/.gitignore @@ -227,4 +227,6 @@ output config.yaml **/tempCodeRunnerFile.py uv.lock -logs/ \ No newline at end of file +logs/ +*.pdf +*.docx \ No newline at end of file diff --git a/src/backend/database.py b/src/backend/database.py index 0dfcbaf..645d023 100644 --- a/src/backend/database.py +++ b/src/backend/database.py @@ -583,25 +583,28 @@ class Database: return self.query_db("SELECT * FROM subjects") # Messages - def addMessage(self, message: dict, user: str, app_id: Union[str, int]): + def addMessage( + self, messages: list[dict[str, Any]], user: str, app_id: Union[str, int] + ): """add a Message to the database Args: - message (dict): the message to be added - user (str): the user who added the message + messages (list[dict[str, Any]]): the messages to be added + user (str): the user who added the messages app_id (Union[str,int]): the id of the apparat """ - def __getUserId(user): + def __getUserId(user: str): return self.query_db( "SELECT id FROM user WHERE username=?", (user,), one=True )[0] user_id = __getUserId(user) - self.query_db( - "INSERT INTO messages (message, user_id, remind_at,appnr) VALUES (?,?,?,?)", - (message["message"], user_id, message["remind_at"], app_id), - ) + for message in messages: + self.query_db( + "INSERT INTO messages (message, user_id, remind_at,appnr) VALUES (?,?,?,?)", + (message["message"], user_id, message["remind_at"], app_id), + ) def getAllMessages(self) -> list[dict[str, str, str, str]]: """Get all the messages in the database @@ -610,7 +613,7 @@ class Database: list[dict[str, str, str, str]]: a list of dictionaries containing the message, the user who added the message, the apparat id and the id of the message """ - def __get_user_name(user_id): + def __get_user_name(user_id: int): return self.query_db( "SELECT username FROM user WHERE id=?", (user_id,), one=True )[0] @@ -628,17 +631,17 @@ class Database: ] return ret - def getMessages(self, date: str) -> list[dict[str, str, str, str]]: + def getMessages(self, date: str) -> list[dict[str, str]]: """Get all the messages for a specific date Args: date (str): a date.datetime object formatted as a string in the format "YYYY-MM-DD" Returns: - list[dict[str, str, str, str]]: a list of dictionaries containing the message, the user who added the message, the apparat id and the id of the message + list[dict[str, str]]: a list of dictionaries containing the message, the user who added the message, the apparat id and the id of the message """ - def __get_user_name(user_id): + def __get_user_name(user_id: int): return self.query_db( "SELECT username FROM user WHERE id=?", (user_id,), one=True )[0] @@ -650,7 +653,7 @@ class Database: ] return ret - def deleteMessage(self, message_id): + def deleteMessage(self, message_id: int): """Delete a message from the database Args: @@ -692,7 +695,9 @@ class Database: )[0] return f"{title} " if title is not None else "" - def getSpecificProfData(self, prof_id: Union[str, int], fields: List[str]) -> tuple: + def getSpecificProfData( + self, prof_id: Union[str, int], fields: List[str] + ) -> tuple[Any, ...]: """A customisable function to get specific data of a professor based on the id Args: @@ -761,7 +766,7 @@ class Database: return [Prof().from_tuple(prof) for prof in profs] # Apparat - def getAllAparats(self, deleted=0) -> list[tuple]: + def getAllAparats(self, deleted: int = 0) -> list[Apparat]: """Get all the apparats in the database Args: @@ -770,9 +775,13 @@ class Database: Returns: list[tuple]: a list of tuples containing the apparats """ - return self.query_db( + apparats = self.query_db( "SELECT * FROM semesterapparat WHERE deletion_status=?", (deleted,) ) + ret: list[Apparat] = [] + for apparat in apparats: + ret.append(Apparat().from_tuple(apparat)) + return ret def getApparatData(self, appnr, appname) -> ApparatData: """Get the Apparat data based on the apparat number and the name @@ -1595,7 +1604,7 @@ class Database: else: return Prof() - def getProfIDByApparat(self, apprarat_id): + def getProfIDByApparat(self, apprarat_id: int) -> Optional[int]: """Get the prof id based on the semesterapparat id from the database Args: @@ -1613,7 +1622,7 @@ class Database: else: return None - def copyBookToApparat(self, book_id, apparat): + def copyBookToApparat(self, book_id: int, apparat: int): # get book data new_apparat_id = apparat new_prof_id = self.getProfIDByApparat(new_apparat_id) @@ -1634,7 +1643,7 @@ class Database: connection.commit() connection.close() - def moveBookToApparat(self, book_id, appratat): + def moveBookToApparat(self, book_id: int, appratat: int): """Move the book to the new apparat Args: @@ -1649,7 +1658,7 @@ class Database: connection.commit() connection.close() - def getApparatNameByAppNr(self, appnr): + def getApparatNameByAppNr(self, appnr: int): query = f"SELECT name FROM semesterapparat WHERE appnr = '{appnr}' and deletion_status = 0" data = self.query_db(query) if data: diff --git a/src/logic/dataclass.py b/src/logic/dataclass.py index a807f87..c3c4f9d 100644 --- a/src/logic/dataclass.py +++ b/src/logic/dataclass.py @@ -1,38 +1,38 @@ - from dataclasses import dataclass, field from enum import Enum import json +from typing import Union, Any, Optional @dataclass class Prof: - id: int = None - _title: str = None - firstname: str = None - lastname: str = None - fullname: str = None - mail: str = None - telnr: str = None + id: Optional[int] = None + _title: Optional[str] = None + firstname: Optional[str] = None + lastname: Optional[str] = None + fullname: Optional[str] = None + mail: Optional[str] = None + telnr: Optional[str] = None # add function that sets the data based on a dict - def from_dict(self, data: dict): + def from_dict(self, data: dict[str, Union[str, int]]): for key, value in data.items(): if hasattr(self, key): setattr(self, key, value) return self @property - def title(self): + def title(self) -> str: if self._title is None or self._title == "None": return "" return self._title @title.setter - def title(self, value): + def title(self, value: str): self._title = value # add function that sets the data from a tuple - def from_tuple(self, data: tuple): + def from_tuple(self, data: tuple[Union[str, int], ...]): setattr(self, "id", data[0]) setattr(self, "_title", data[1]) setattr(self, "firstname", data[2]) @@ -42,7 +42,7 @@ class Prof: setattr(self, "telnr", data[6]) return self - def name(self, comma=False): + def name(self, comma: bool = False) -> Optional[str]: if self.firstname is None and self.lastname is None: if "," in self.fullname: self.firstname = self.fullname.split(",")[1].strip() @@ -62,9 +62,9 @@ class BookData: signature: str | None = None edition: str | None = None link: str | None = None - isbn: str | list | None = field(default_factory=list) + isbn: Union[str, list[str], None] = field(default_factory=list) author: str | None = None - language: str | list | None = field(default_factory=list) + language: Union[str, list[str], None] = field(default_factory=list) publisher: str | None = None place: str | None = None year: str | None = None @@ -73,31 +73,33 @@ class BookData: in_apparat: bool | None = False adis_idn: str | None = None - def from_dict(self, data: dict): + def from_dict(self, data: dict) -> "BookData": for key, value in data.items(): setattr(self, key, value) + return self @property - def to_dict(self): + def to_dict(self) -> str: """Convert the dataclass to a dictionary.""" return json.dumps(self.__dict__, ensure_ascii=False) - def from_dataclass(self, dataclass): + def from_dataclass(self, dataclass: Optional[Any]) -> None: + if dataclass is None: + return for key, value in dataclass.__dict__.items(): setattr(self, key, value) - def from_string(self, data: str): - data = json.loads(data) - - return BookData(**data) + def from_string(self, data: str) -> "BookData": + ndata = json.loads(data) + return BookData(**ndata) @dataclass class MailData: - subject: str | None = None - body: str | None = None - mailto: str | None = None - prof: str | None = None + subject: Optional[str] = None + body: Optional[str] = None + mailto: Optional[str] = None + prof: Optional[str] = None class Subjects(Enum): @@ -127,15 +129,15 @@ class Subjects(Enum): ECONOMICS = (24, "Wirtschaftslehre") @property - def id(self): + def id(self) -> int: return self.value[0] @property - def name(self): + def name(self) -> str: return self.value[1] @classmethod - def get_index(cls, name): + def get_index(cls, name: str) -> Optional[int]: for i in cls: if i.name == name: return i.id - 1 @@ -158,7 +160,7 @@ class Apparat: prof_id_adis: str | None = None konto: int | None = None - def from_tuple(self, data: tuple): + def from_tuple(self, data: tuple[Any, ...]) -> "Apparat": self.id = data[0] self.name = data[1] self.prof_id = data[2] @@ -176,7 +178,7 @@ class Apparat: return self @property - def get_semester(self): + def get_semester(self) -> Optional[str]: if self.extend_until is not None: return self.extend_until else: @@ -190,7 +192,7 @@ class ELSA: semester: str | None = None prof_id: int | None = None - def from_tuple(self, data): + def from_tuple(self, data: tuple[Any, ...]) -> "ELSA": self.id = data[0] self.date = data[1] self.semester = data[2] diff --git a/src/ui/dialogs/dialog_sources/settings_ui.py b/src/ui/dialogs/dialog_sources/settings_ui.py index 288c9ff..92015d7 100644 --- a/src/ui/dialogs/dialog_sources/settings_ui.py +++ b/src/ui/dialogs/dialog_sources/settings_ui.py @@ -1,6 +1,6 @@ # 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.8.0 +# Created by: PyQt6 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. diff --git a/src/ui/dialogs/parsed_titles_ui.py b/src/ui/dialogs/parsed_titles_ui.py index 15fb6af..7f643c8 100644 --- a/src/ui/dialogs/parsed_titles_ui.py +++ b/src/ui/dialogs/parsed_titles_ui.py @@ -1,6 +1,6 @@ -# Form implementation generated from reading ui file '/home/alexander/GitHub/Semesterapparate/ui/dialogs/parsed_titles.ui' +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\dialogs\parsed_titles.ui' # -# Created by: PyQt6 UI code generator 6.5.3 +# Created by: PyQt6 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. @@ -38,12 +38,7 @@ class Ui_Form(object): self.label_2 = QtWidgets.QLabel(parent=self.horizontalLayoutWidget) self.label_2.setObjectName("label_2") self.horizontalLayout.addWidget(self.label_2) - spacerItem = QtWidgets.QSpacerItem( - 40, - 20, - QtWidgets.QSizePolicy.Policy.Expanding, - QtWidgets.QSizePolicy.Policy.Minimum, - ) + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) self.horizontalLayout.addItem(spacerItem) self.frame_2 = QtWidgets.QFrame(parent=Form) self.frame_2.setGeometry(QtCore.QRect(10, 80, 381, 201)) @@ -59,9 +54,7 @@ class Ui_Form(object): self.listWidget = QtWidgets.QListWidget(parent=self.horizontalLayoutWidget_2) self.listWidget.setObjectName("listWidget") self.horizontalLayout_2.addWidget(self.listWidget) - self.listWidget_done = QtWidgets.QListWidget( - parent=self.horizontalLayoutWidget_2 - ) + self.listWidget_done = QtWidgets.QListWidget(parent=self.horizontalLayoutWidget_2) self.listWidget_done.setObjectName("listWidget_done") self.horizontalLayout_2.addWidget(self.listWidget_done) self.progressBar = QtWidgets.QProgressBar(parent=Form) @@ -70,10 +63,7 @@ class Ui_Form(object): self.progressBar.setObjectName("progressBar") self.buttonBox = QtWidgets.QDialogButtonBox(parent=Form) self.buttonBox.setGeometry(QtCore.QRect(230, 290, 156, 23)) - self.buttonBox.setStandardButtons( - QtWidgets.QDialogButtonBox.StandardButton.Cancel - | QtWidgets.QDialogButtonBox.StandardButton.Ok - ) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok) self.buttonBox.setObjectName("buttonBox") self.toolButton = QtWidgets.QToolButton(parent=Form) self.toolButton.setGeometry(QtCore.QRect(20, 290, 25, 19)) diff --git a/src/ui/dialogs/reminder.py b/src/ui/dialogs/reminder.py index 4e096ff..54ec66e 100644 --- a/src/ui/dialogs/reminder.py +++ b/src/ui/dialogs/reminder.py @@ -3,7 +3,7 @@ from PyQt6 import QtWidgets from .dialog_sources.reminder_ui import Ui_Erinnerung as Ui_Dialog from src import Icon import datetime as date - +from typing import Any class ReminderDialog(QtWidgets.QDialog, Ui_Dialog): def __init__(self, parent=None): @@ -13,8 +13,10 @@ class ReminderDialog(QtWidgets.QDialog, Ui_Dialog): self.setWindowTitle("Erinnerung") self.dateEdit.setDate(date.datetime.now()) - def return_message(self) -> dict: - return { - "message": self.message_box.toPlainText(), - "remind_at": self.dateEdit.date().toString("yyyy-MM-dd"), - } + def return_message(self) -> list[dict[str, Any]]: + return [ + { + "message": self.message_box.toPlainText(), + "remind_at": self.dateEdit.date().toString("yyyy-MM-dd"), + } + ] diff --git a/src/ui/sounds/semesterapparat_ui_ui.py b/src/ui/sounds/semesterapparat_ui_ui.py index 7ed30a8..657741f 100644 --- a/src/ui/sounds/semesterapparat_ui_ui.py +++ b/src/ui/sounds/semesterapparat_ui_ui.py @@ -1,6 +1,6 @@ # Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\SemesterapparatsManager\src\ui\sounds\semesterapparat_ui.ui' # -# Created by: PyQt6 UI code generator 6.8.0 +# Created by: PyQt6 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. diff --git a/src/ui/userInterface.py b/src/ui/userInterface.py index 6619a0d..fb45198 100644 --- a/src/ui/userInterface.py +++ b/src/ui/userInterface.py @@ -1,7 +1,7 @@ # encoding: utf-8 import atexit import os - +import time import sys import tempfile import webbrowser @@ -260,7 +260,7 @@ class Ui(Ui_Semesterapparat): def create_doc(self): log.debug("Creating document") # open DocumentPrintDialog - dialog = DocumentPrintDialog(self.MainWindow) + dialog = DocumentPrintDialog(self.MainWindow) # type: ignore dialog.show() def checkValidInput(self): @@ -269,24 +269,24 @@ class Ui(Ui_Semesterapparat): else: self.check_file.setEnabled(False) - def setWidget(self, widget): + def setWidget(self, widget: QtWidgets.QWidget): # remove all widgets from localwidget self.hideWidget() # add widget to localwidget - self.admin_action.layout().addWidget(widget) + self.admin_action.layout().addWidget(widget) # type: ignore def hideWidget(self): try: widgets = [ - self.admin_action.layout().itemAt(i).widget() - for i in range(self.admin_action.layout().count()) + self.admin_action.layout().itemAt(i).widget() # type: ignore + for i in range(self.admin_action.layout().count()) # type: ignore ] except AttributeError: return for widget in widgets: - self.admin_action.layout().removeWidget(widget) - widget.deleteLater() + self.admin_action.layout().removeWidget(widget) # type: ignore + widget.deleteLater() # type: ignore def adminActions(self): if self.select_action_box.currentText() == "Nutzer anlegen": @@ -302,7 +302,7 @@ class Ui(Ui_Semesterapparat): self.hideWidget() self.admin_action.setTitle("") - def toggleButton(self, button): + def toggleButton(self, button: QtWidgets.QCheckBox): if button.isChecked(): button.setChecked(False) self.validate_semester() @@ -317,7 +317,7 @@ class Ui(Ui_Semesterapparat): def get_apparats(self): alist = self.db.getAllAparats(deleted=0) - alist = natsorted(alist, key=lambda x: x[4], reverse=True) + alist = natsorted(alist, key=lambda x: x.appnr, reverse=True) self.tableWidget_apparate.setRowCount(0) for apparat in alist: self.insert_apparat_into_table(apparat) @@ -327,15 +327,16 @@ class Ui(Ui_Semesterapparat): self.app_fach.clear() self.app_fach.addItem("") self.app_fach.setCurrentText("") - self.app_fach.addItems([subject[1] for subject in self.db.getSubjects()]) + self.app_fach.addItems([subject[1] for subject in self.db.getSubjects()]) # type: ignore def open_documentation(self): log.info("Opening Documentation") if not self.docu.isRunning(): self.docu.start() + time.sleep(5) webbrowser.open("http://localhost:8000") - def update_calendar(self, data): + def update_calendar(self, data: list[dict[str, Any]]): self.calendarWidget.setMessages([data]) self.calendarWidget.updateCells() @@ -459,8 +460,7 @@ class Ui(Ui_Semesterapparat): else self.sem_winter.text() + " " + self.sem_year.text() ) app.prof_id_adis = self.prof_id_adis.text() - prof_id = self.db.getProfByName(prof.fullname).id - self.add_files(prof_id) + self.add_files() app.apparat_id_adis = self.apparat_id_adis.text() appdata = ApparatData(prof=prof, apparat=app) self.db.updateApparat(appdata) @@ -1305,7 +1305,7 @@ class Ui(Ui_Semesterapparat): "prof_tel": self.prof_tel_nr.text(), } - def add_files(self, prof_id=None): + def add_files(self): """ Add Files to the associated prof in the database @@ -1346,24 +1346,28 @@ class Ui(Ui_Semesterapparat): self.insert_apparat_into_table(apparat) log.info("Inserted {} apparats into table".format(len(self.apparats))) - def insert_apparat_into_table(self, apparat): + def insert_apparat_into_table(self, apparat: Apparat): # log.debug(apparat) - def __dauer_check(apparat): - return "Ja" if apparat[7] == 1 else "Nein" + def __dauer_check(apparat: Apparat): + return "Ja" if apparat.eternal == 1 else "Nein" - semester = apparat[8] if apparat[8] is not None else apparat[5] + semester = ( + apparat.extend_until + if apparat.extend_until is not None + else apparat.created_semester + ) self.tableWidget_apparate.insertRow(0) self.tableWidget_apparate.setItem( - 0, 0, QtWidgets.QTableWidgetItem(str(apparat[4])) + 0, 0, QtWidgets.QTableWidgetItem(str(apparat.appnr)) ) self.tableWidget_apparate.setItem( - 0, 1, QtWidgets.QTableWidgetItem(str(apparat[1])) + 0, 1, QtWidgets.QTableWidgetItem(str(apparat.name)) ) self.tableWidget_apparate.setItem( 0, 2, QtWidgets.QTableWidgetItem( - self.db.getProfNameById(apparat[2], add_title=False) + self.db.getProfNameById(apparat.prof_id, add_title=False) ), ) self.tableWidget_apparate.setItem( @@ -1375,7 +1379,7 @@ class Ui(Ui_Semesterapparat): 0, 4, QtWidgets.QTableWidgetItem(__dauer_check(apparat)) ) self.tableWidget_apparate.setItem( - 0, 5, QtWidgets.QTableWidgetItem(str(apparat[13])) + 0, 5, QtWidgets.QTableWidgetItem(str(apparat.konto)) ) def open_context_menu(self, position): @@ -1440,7 +1444,7 @@ class Ui(Ui_Semesterapparat): dialog = CalendarEntry(messages=messages, date=selected_date) # append dialog to self.frame_2 self.calendarlayout.addWidget(dialog) - dialog.repaintSignal.connect(lambda: self.calendarWidget.reload(selected_date)) + dialog.repaintSignal.connect(lambda: self.calendarWidget.reload(selected_date)) # type: ignore def open_settings(self): # log.debug(settings.dict()) @@ -1463,7 +1467,7 @@ class Ui(Ui_Semesterapparat): else: pass - def media_context_menu(self, position): + def media_context_menu(self, position): # type: ignore menu = QtWidgets.QMenu() delete_action = QtGui.QAction("Löschen") @@ -1475,36 +1479,36 @@ class Ui(Ui_Semesterapparat): apparatmenu = menu.addMenu("Apparate") generalmenu = menu.addMenu("Allgemeines") - apparatmenu.addActions( + apparatmenu.addActions( # type: ignore [apparat_add_action, apparat_copy_action, apparat_move_action] ) - generalmenu.addActions([edit_action, delete_action, update_data_action]) + generalmenu.addActions([edit_action, delete_action, update_data_action]) # type: ignore # disable apparat_add_action apparat_add_action.setEnabled(False) - delete_action.triggered.connect(self.delete_medium) - edit_action.triggered.connect(self.edit_medium) - apparat_add_action.triggered.connect(self.add_to_apparat) - apparat_copy_action.triggered.connect(self.copy_to_apparat) - apparat_move_action.triggered.connect(self.move_to_apparat) - update_data_action.triggered.connect(self.update_data) - menu.exec(self.tableWidget_apparat_media.mapToGlobal(position)) + delete_action.triggered.connect(self.delete_medium) # type: ignore + edit_action.triggered.connect(self.edit_medium) # type: ignore + apparat_add_action.triggered.connect(self.add_to_apparat) # type: ignore + apparat_copy_action.triggered.connect(self.copy_to_apparat) # type: ignore + apparat_move_action.triggered.connect(self.move_to_apparat) # type: ignore + update_data_action.triggered.connect(self.update_data) # type: ignore + menu.exec(self.tableWidget_apparat_media.mapToGlobal(position)) # type: ignore def update_data(self): # TODO: use link in table, parse data and if needed, update location / signature pass def copy_to_apparat(self): - selected_rows = self.tableWidget_apparat_media.selectionModel().selectedRows() - signatures = [] + selected_rows = self.tableWidget_apparat_media.selectionModel().selectedRows() # type: ignore + signatures: list[int] = [] for row in selected_rows: - signature = self.tableWidget_apparat_media.item(row.row(), 1).text() + signature = self.tableWidget_apparat_media.item(row.row(), 1).text() # type: ignore book_id = self.db.getBookIdBasedOnSignature( self.active_apparat, - self.db.getProfId(self.profdata), + self.db.getProfId(self.profdata), # type: ignore signature, ) - signatures.append(book_id) - result, apparat = self.confirm_action_dialog( + signatures.append(book_id) # type: ignore + result, apparat = self.confirm_action_dialog( # type: ignore "In welchen Apparat sollen die Medien kopiert werden?" ) if result == 1: diff --git a/src/ui/widgets/MessageCalendar.py b/src/ui/widgets/MessageCalendar.py index 48d93eb..487153e 100644 --- a/src/ui/widgets/MessageCalendar.py +++ b/src/ui/widgets/MessageCalendar.py @@ -2,6 +2,7 @@ from PyQt6 import QtWidgets, QtCore from PyQt6.QtCore import QDate from PyQt6.QtGui import QColor, QPen from src.backend import Database +from typing import Any import darkdetect import loguru import sys @@ -37,7 +38,7 @@ class MessageCalendar(QtWidgets.QCalendarWidget): self.messages.remove(message) self.updateCells() - def setMessages(self, messages): + def setMessages(self, messages: list[dict[str, Any]]): # remove all drawn circles for message in messages: diff --git a/src/ui/widgets/graph.py b/src/ui/widgets/graph.py index a7a389f..cc9cfc0 100644 --- a/src/ui/widgets/graph.py +++ b/src/ui/widgets/graph.py @@ -1,5 +1,5 @@ import random -from typing import Union +from typing import Union, Any import pyqtgraph as pg from PyQt6 import QtWidgets @@ -12,8 +12,8 @@ log.add(sys.stdout) log.add("logs/application.log", rotation="1 MB", retention="10 days") -def mergedicts(d1, d2): - res = {} +def mergedicts(d1: dict[str, Any], d2: dict[str, Any]): + res: dict[str, Any] = {} d1_data = list(d1.items()) d2_data = list(d2.items()) for i in range(len(d1)): @@ -24,18 +24,18 @@ def mergedicts(d1, d2): d1_dict = dict([d1_data_slice]) d2_dict = dict([d2_data_slice]) # merge the dicts - res.update(d1_dict) - res.update(d2_dict) + res.update(d1_dict) # type: ignore + res.update(d2_dict) # type: ignore return res class DataGraph(QtWidgets.QWidget): def __init__( self, - title, - data=Union[dict[list, list] | dict[list[dict[str, list]]]], - generateMissing=False, - label=None, + title: str, + data=Union[dict[list, list], dict[list[dict[str, list[Any]]]]], + generateMissing: bool = False, + label: str = None, ): super().__init__() log.debug(