Refactor database message handling to support multiple messages and enhance type hints across various classes

This commit is contained in:
2025-05-14 14:34:40 +02:00
parent f7c499ea6e
commit 0c53778f99
6 changed files with 126 additions and 108 deletions

View File

@@ -583,21 +583,24 @@ class Database:
return self.query_db("SELECT * FROM subjects") return self.query_db("SELECT * FROM subjects")
# Messages # 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 """add a Message to the database
Args: Args:
message (dict): the message to be added messages (list[dict[str, Any]]): the messages to be added
user (str): the user who added the message user (str): the user who added the messages
app_id (Union[str,int]): the id of the apparat app_id (Union[str,int]): the id of the apparat
""" """
def __getUserId(user): def __getUserId(user: str):
return self.query_db( return self.query_db(
"SELECT id FROM user WHERE username=?", (user,), one=True "SELECT id FROM user WHERE username=?", (user,), one=True
)[0] )[0]
user_id = __getUserId(user) user_id = __getUserId(user)
for message in messages:
self.query_db( self.query_db(
"INSERT INTO messages (message, user_id, remind_at,appnr) VALUES (?,?,?,?)", "INSERT INTO messages (message, user_id, remind_at,appnr) VALUES (?,?,?,?)",
(message["message"], user_id, message["remind_at"], app_id), (message["message"], user_id, message["remind_at"], app_id),
@@ -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 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( return self.query_db(
"SELECT username FROM user WHERE id=?", (user_id,), one=True "SELECT username FROM user WHERE id=?", (user_id,), one=True
)[0] )[0]
@@ -628,17 +631,17 @@ class Database:
] ]
return ret 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 """Get all the messages for a specific date
Args: Args:
date (str): a date.datetime object formatted as a string in the format "YYYY-MM-DD" date (str): a date.datetime object formatted as a string in the format "YYYY-MM-DD"
Returns: 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( return self.query_db(
"SELECT username FROM user WHERE id=?", (user_id,), one=True "SELECT username FROM user WHERE id=?", (user_id,), one=True
)[0] )[0]
@@ -650,7 +653,7 @@ class Database:
] ]
return ret return ret
def deleteMessage(self, message_id): def deleteMessage(self, message_id: int):
"""Delete a message from the database """Delete a message from the database
Args: Args:
@@ -692,7 +695,9 @@ class Database:
)[0] )[0]
return f"{title} " if title is not None else "" 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 """A customisable function to get specific data of a professor based on the id
Args: Args:
@@ -761,7 +766,7 @@ class Database:
return [Prof().from_tuple(prof) for prof in profs] return [Prof().from_tuple(prof) for prof in profs]
# Apparat # Apparat
def getAllAparats(self, deleted=0) -> list[tuple]: def getAllAparats(self, deleted: int = 0) -> list[Apparat]:
"""Get all the apparats in the database """Get all the apparats in the database
Args: Args:
@@ -770,9 +775,13 @@ class Database:
Returns: Returns:
list[tuple]: a list of tuples containing the apparats list[tuple]: a list of tuples containing the apparats
""" """
return self.query_db( apparats = self.query_db(
"SELECT * FROM semesterapparat WHERE deletion_status=?", (deleted,) "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: def getApparatData(self, appnr, appname) -> ApparatData:
"""Get the Apparat data based on the apparat number and the name """Get the Apparat data based on the apparat number and the name
@@ -1595,7 +1604,7 @@ class Database:
else: else:
return Prof() 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 """Get the prof id based on the semesterapparat id from the database
Args: Args:
@@ -1613,7 +1622,7 @@ class Database:
else: else:
return None return None
def copyBookToApparat(self, book_id, apparat): def copyBookToApparat(self, book_id: int, apparat: int):
# get book data # get book data
new_apparat_id = apparat new_apparat_id = apparat
new_prof_id = self.getProfIDByApparat(new_apparat_id) new_prof_id = self.getProfIDByApparat(new_apparat_id)
@@ -1634,7 +1643,7 @@ class Database:
connection.commit() connection.commit()
connection.close() connection.close()
def moveBookToApparat(self, book_id, appratat): def moveBookToApparat(self, book_id: int, appratat: int):
"""Move the book to the new apparat """Move the book to the new apparat
Args: Args:
@@ -1649,7 +1658,7 @@ class Database:
connection.commit() connection.commit()
connection.close() connection.close()
def getApparatNameByAppNr(self, appnr): def getApparatNameByAppNr(self, appnr: int):
query = f"SELECT name FROM semesterapparat WHERE appnr = '{appnr}' and deletion_status = 0" query = f"SELECT name FROM semesterapparat WHERE appnr = '{appnr}' and deletion_status = 0"
data = self.query_db(query) data = self.query_db(query)
if data: if data:

View File

@@ -1,38 +1,38 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum from enum import Enum
import json import json
from typing import Union, Any, Optional
@dataclass @dataclass
class Prof: class Prof:
id: int = None id: Optional[int] = None
_title: str = None _title: Optional[str] = None
firstname: str = None firstname: Optional[str] = None
lastname: str = None lastname: Optional[str] = None
fullname: str = None fullname: Optional[str] = None
mail: str = None mail: Optional[str] = None
telnr: str = None telnr: Optional[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): def from_dict(self, data: dict[str, Union[str, int]]):
for key, value in data.items(): for key, value in data.items():
if hasattr(self, key): if hasattr(self, key):
setattr(self, key, value) setattr(self, key, value)
return self return self
@property @property
def title(self): def title(self) -> str:
if self._title is None or self._title == "None": if self._title is None or self._title == "None":
return "" return ""
return self._title return self._title
@title.setter @title.setter
def title(self, value): def title(self, value: str):
self._title = 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): def from_tuple(self, data: tuple[Union[str, int], ...]):
setattr(self, "id", data[0]) setattr(self, "id", data[0])
setattr(self, "_title", data[1]) setattr(self, "_title", data[1])
setattr(self, "firstname", data[2]) setattr(self, "firstname", data[2])
@@ -42,7 +42,7 @@ class Prof:
setattr(self, "telnr", data[6]) setattr(self, "telnr", data[6])
return self 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 self.firstname is None and self.lastname is None:
if "," in self.fullname: if "," in self.fullname:
self.firstname = self.fullname.split(",")[1].strip() self.firstname = self.fullname.split(",")[1].strip()
@@ -62,9 +62,9 @@ class BookData:
signature: str | None = None signature: str | None = None
edition: str | None = None edition: str | None = None
link: 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 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 publisher: str | None = None
place: str | None = None place: str | None = None
year: str | None = None year: str | None = None
@@ -73,31 +73,33 @@ class BookData:
in_apparat: bool | None = False in_apparat: bool | None = False
adis_idn: str | None = None adis_idn: str | None = None
def from_dict(self, data: dict): def from_dict(self, data: dict) -> "BookData":
for key, value in data.items(): for key, value in data.items():
setattr(self, key, value) setattr(self, key, value)
return self
@property @property
def to_dict(self): def to_dict(self) -> str:
"""Convert the dataclass to a dictionary.""" """Convert the dataclass to a dictionary."""
return json.dumps(self.__dict__, ensure_ascii=False) 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(): for key, value in dataclass.__dict__.items():
setattr(self, key, value) setattr(self, key, value)
def from_string(self, data: str): def from_string(self, data: str) -> "BookData":
data = json.loads(data) ndata = json.loads(data)
return BookData(**ndata)
return BookData(**data)
@dataclass @dataclass
class MailData: class MailData:
subject: str | None = None subject: Optional[str] = None
body: str | None = None body: Optional[str] = None
mailto: str | None = None mailto: Optional[str] = None
prof: str | None = None prof: Optional[str] = None
class Subjects(Enum): class Subjects(Enum):
@@ -127,15 +129,15 @@ class Subjects(Enum):
ECONOMICS = (24, "Wirtschaftslehre") ECONOMICS = (24, "Wirtschaftslehre")
@property @property
def id(self): def id(self) -> int:
return self.value[0] return self.value[0]
@property @property
def name(self): def name(self) -> str:
return self.value[1] return self.value[1]
@classmethod @classmethod
def get_index(cls, name): def get_index(cls, name: str) -> Optional[int]:
for i in cls: for i in cls:
if i.name == name: if i.name == name:
return i.id - 1 return i.id - 1
@@ -158,7 +160,7 @@ class Apparat:
prof_id_adis: str | None = None prof_id_adis: str | None = None
konto: int | 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.id = data[0]
self.name = data[1] self.name = data[1]
self.prof_id = data[2] self.prof_id = data[2]
@@ -176,7 +178,7 @@ class Apparat:
return self return self
@property @property
def get_semester(self): def get_semester(self) -> Optional[str]:
if self.extend_until is not None: if self.extend_until is not None:
return self.extend_until return self.extend_until
else: else:
@@ -190,7 +192,7 @@ class ELSA:
semester: str | None = None semester: str | None = None
prof_id: int | 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.id = data[0]
self.date = data[1] self.date = data[1]
self.semester = data[2] self.semester = data[2]

View File

@@ -3,7 +3,7 @@ from PyQt6 import QtWidgets
from .dialog_sources.reminder_ui import Ui_Erinnerung as Ui_Dialog from .dialog_sources.reminder_ui import Ui_Erinnerung as Ui_Dialog
from src import Icon from src import Icon
import datetime as date import datetime as date
from typing import Any
class ReminderDialog(QtWidgets.QDialog, Ui_Dialog): class ReminderDialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None): def __init__(self, parent=None):
@@ -13,8 +13,10 @@ class ReminderDialog(QtWidgets.QDialog, Ui_Dialog):
self.setWindowTitle("Erinnerung") self.setWindowTitle("Erinnerung")
self.dateEdit.setDate(date.datetime.now()) self.dateEdit.setDate(date.datetime.now())
def return_message(self) -> dict: def return_message(self) -> list[dict[str, Any]]:
return { return [
{
"message": self.message_box.toPlainText(), "message": self.message_box.toPlainText(),
"remind_at": self.dateEdit.date().toString("yyyy-MM-dd"), "remind_at": self.dateEdit.date().toString("yyyy-MM-dd"),
} }
]

View File

@@ -1,7 +1,7 @@
# encoding: utf-8 # encoding: utf-8
import atexit import atexit
import os import os
import time
import sys import sys
import tempfile import tempfile
import webbrowser import webbrowser
@@ -260,7 +260,7 @@ class Ui(Ui_Semesterapparat):
def create_doc(self): def create_doc(self):
log.debug("Creating document") log.debug("Creating document")
# open DocumentPrintDialog # open DocumentPrintDialog
dialog = DocumentPrintDialog(self.MainWindow) dialog = DocumentPrintDialog(self.MainWindow) # type: ignore
dialog.show() dialog.show()
def checkValidInput(self): def checkValidInput(self):
@@ -269,24 +269,24 @@ class Ui(Ui_Semesterapparat):
else: else:
self.check_file.setEnabled(False) self.check_file.setEnabled(False)
def setWidget(self, widget): def setWidget(self, widget: QtWidgets.QWidget):
# remove all widgets from localwidget # remove all widgets from localwidget
self.hideWidget() self.hideWidget()
# add widget to localwidget # add widget to localwidget
self.admin_action.layout().addWidget(widget) self.admin_action.layout().addWidget(widget) # type: ignore
def hideWidget(self): def hideWidget(self):
try: try:
widgets = [ widgets = [
self.admin_action.layout().itemAt(i).widget() self.admin_action.layout().itemAt(i).widget() # type: ignore
for i in range(self.admin_action.layout().count()) for i in range(self.admin_action.layout().count()) # type: ignore
] ]
except AttributeError: except AttributeError:
return return
for widget in widgets: for widget in widgets:
self.admin_action.layout().removeWidget(widget) self.admin_action.layout().removeWidget(widget) # type: ignore
widget.deleteLater() widget.deleteLater() # type: ignore
def adminActions(self): def adminActions(self):
if self.select_action_box.currentText() == "Nutzer anlegen": if self.select_action_box.currentText() == "Nutzer anlegen":
@@ -302,7 +302,7 @@ class Ui(Ui_Semesterapparat):
self.hideWidget() self.hideWidget()
self.admin_action.setTitle("") self.admin_action.setTitle("")
def toggleButton(self, button): def toggleButton(self, button: QtWidgets.QCheckBox):
if button.isChecked(): if button.isChecked():
button.setChecked(False) button.setChecked(False)
self.validate_semester() self.validate_semester()
@@ -317,7 +317,7 @@ class Ui(Ui_Semesterapparat):
def get_apparats(self): def get_apparats(self):
alist = self.db.getAllAparats(deleted=0) 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) self.tableWidget_apparate.setRowCount(0)
for apparat in alist: for apparat in alist:
self.insert_apparat_into_table(apparat) self.insert_apparat_into_table(apparat)
@@ -327,15 +327,16 @@ class Ui(Ui_Semesterapparat):
self.app_fach.clear() self.app_fach.clear()
self.app_fach.addItem("") self.app_fach.addItem("")
self.app_fach.setCurrentText("") 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): def open_documentation(self):
log.info("Opening Documentation") log.info("Opening Documentation")
if not self.docu.isRunning(): if not self.docu.isRunning():
self.docu.start() self.docu.start()
time.sleep(5)
webbrowser.open("http://localhost:8000") 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.setMessages([data])
self.calendarWidget.updateCells() self.calendarWidget.updateCells()
@@ -459,8 +460,7 @@ class Ui(Ui_Semesterapparat):
else self.sem_winter.text() + " " + self.sem_year.text() else self.sem_winter.text() + " " + self.sem_year.text()
) )
app.prof_id_adis = self.prof_id_adis.text() app.prof_id_adis = self.prof_id_adis.text()
prof_id = self.db.getProfByName(prof.fullname).id self.add_files()
self.add_files(prof_id)
app.apparat_id_adis = self.apparat_id_adis.text() app.apparat_id_adis = self.apparat_id_adis.text()
appdata = ApparatData(prof=prof, apparat=app) appdata = ApparatData(prof=prof, apparat=app)
self.db.updateApparat(appdata) self.db.updateApparat(appdata)
@@ -1305,7 +1305,7 @@ class Ui(Ui_Semesterapparat):
"prof_tel": self.prof_tel_nr.text(), "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 Add Files to the associated prof in the database
@@ -1346,24 +1346,28 @@ class Ui(Ui_Semesterapparat):
self.insert_apparat_into_table(apparat) self.insert_apparat_into_table(apparat)
log.info("Inserted {} apparats into table".format(len(self.apparats))) 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) # log.debug(apparat)
def __dauer_check(apparat): def __dauer_check(apparat: Apparat):
return "Ja" if apparat[7] == 1 else "Nein" 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.insertRow(0)
self.tableWidget_apparate.setItem( self.tableWidget_apparate.setItem(
0, 0, QtWidgets.QTableWidgetItem(str(apparat[4])) 0, 0, QtWidgets.QTableWidgetItem(str(apparat.appnr))
) )
self.tableWidget_apparate.setItem( self.tableWidget_apparate.setItem(
0, 1, QtWidgets.QTableWidgetItem(str(apparat[1])) 0, 1, QtWidgets.QTableWidgetItem(str(apparat.name))
) )
self.tableWidget_apparate.setItem( self.tableWidget_apparate.setItem(
0, 0,
2, 2,
QtWidgets.QTableWidgetItem( QtWidgets.QTableWidgetItem(
self.db.getProfNameById(apparat[2], add_title=False) self.db.getProfNameById(apparat.prof_id, add_title=False)
), ),
) )
self.tableWidget_apparate.setItem( self.tableWidget_apparate.setItem(
@@ -1375,7 +1379,7 @@ class Ui(Ui_Semesterapparat):
0, 4, QtWidgets.QTableWidgetItem(__dauer_check(apparat)) 0, 4, QtWidgets.QTableWidgetItem(__dauer_check(apparat))
) )
self.tableWidget_apparate.setItem( self.tableWidget_apparate.setItem(
0, 5, QtWidgets.QTableWidgetItem(str(apparat[13])) 0, 5, QtWidgets.QTableWidgetItem(str(apparat.konto))
) )
def open_context_menu(self, position): def open_context_menu(self, position):
@@ -1440,7 +1444,7 @@ class Ui(Ui_Semesterapparat):
dialog = CalendarEntry(messages=messages, date=selected_date) dialog = CalendarEntry(messages=messages, date=selected_date)
# append dialog to self.frame_2 # append dialog to self.frame_2
self.calendarlayout.addWidget(dialog) 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): def open_settings(self):
# log.debug(settings.dict()) # log.debug(settings.dict())
@@ -1463,7 +1467,7 @@ class Ui(Ui_Semesterapparat):
else: else:
pass pass
def media_context_menu(self, position): def media_context_menu(self, position): # type: ignore
menu = QtWidgets.QMenu() menu = QtWidgets.QMenu()
delete_action = QtGui.QAction("Löschen") delete_action = QtGui.QAction("Löschen")
@@ -1475,36 +1479,36 @@ class Ui(Ui_Semesterapparat):
apparatmenu = menu.addMenu("Apparate") apparatmenu = menu.addMenu("Apparate")
generalmenu = menu.addMenu("Allgemeines") generalmenu = menu.addMenu("Allgemeines")
apparatmenu.addActions( apparatmenu.addActions( # type: ignore
[apparat_add_action, apparat_copy_action, apparat_move_action] [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 # disable apparat_add_action
apparat_add_action.setEnabled(False) apparat_add_action.setEnabled(False)
delete_action.triggered.connect(self.delete_medium) delete_action.triggered.connect(self.delete_medium) # type: ignore
edit_action.triggered.connect(self.edit_medium) edit_action.triggered.connect(self.edit_medium) # type: ignore
apparat_add_action.triggered.connect(self.add_to_apparat) apparat_add_action.triggered.connect(self.add_to_apparat) # type: ignore
apparat_copy_action.triggered.connect(self.copy_to_apparat) apparat_copy_action.triggered.connect(self.copy_to_apparat) # type: ignore
apparat_move_action.triggered.connect(self.move_to_apparat) apparat_move_action.triggered.connect(self.move_to_apparat) # type: ignore
update_data_action.triggered.connect(self.update_data) update_data_action.triggered.connect(self.update_data) # type: ignore
menu.exec(self.tableWidget_apparat_media.mapToGlobal(position)) menu.exec(self.tableWidget_apparat_media.mapToGlobal(position)) # type: ignore
def update_data(self): def update_data(self):
# TODO: use link in table, parse data and if needed, update location / signature # TODO: use link in table, parse data and if needed, update location / signature
pass pass
def copy_to_apparat(self): def copy_to_apparat(self):
selected_rows = self.tableWidget_apparat_media.selectionModel().selectedRows() selected_rows = self.tableWidget_apparat_media.selectionModel().selectedRows() # type: ignore
signatures = [] signatures: list[int] = []
for row in selected_rows: 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( book_id = self.db.getBookIdBasedOnSignature(
self.active_apparat, self.active_apparat,
self.db.getProfId(self.profdata), self.db.getProfId(self.profdata), # type: ignore
signature, signature,
) )
signatures.append(book_id) signatures.append(book_id) # type: ignore
result, apparat = self.confirm_action_dialog( result, apparat = self.confirm_action_dialog( # type: ignore
"In welchen Apparat sollen die Medien kopiert werden?" "In welchen Apparat sollen die Medien kopiert werden?"
) )
if result == 1: if result == 1:

View File

@@ -2,6 +2,7 @@ from PyQt6 import QtWidgets, QtCore
from PyQt6.QtCore import QDate from PyQt6.QtCore import QDate
from PyQt6.QtGui import QColor, QPen from PyQt6.QtGui import QColor, QPen
from src.backend import Database from src.backend import Database
from typing import Any
import darkdetect import darkdetect
import loguru import loguru
import sys import sys
@@ -37,7 +38,7 @@ class MessageCalendar(QtWidgets.QCalendarWidget):
self.messages.remove(message) self.messages.remove(message)
self.updateCells() self.updateCells()
def setMessages(self, messages): def setMessages(self, messages: list[dict[str, Any]]):
# remove all drawn circles # remove all drawn circles
for message in messages: for message in messages:

View File

@@ -1,5 +1,5 @@
import random import random
from typing import Union from typing import Union, Any
import pyqtgraph as pg import pyqtgraph as pg
from PyQt6 import QtWidgets from PyQt6 import QtWidgets
@@ -12,8 +12,8 @@ log.add(sys.stdout)
log.add("logs/application.log", rotation="1 MB", retention="10 days") log.add("logs/application.log", rotation="1 MB", retention="10 days")
def mergedicts(d1, d2): def mergedicts(d1: dict[str, Any], d2: dict[str, Any]):
res = {} res: dict[str, Any] = {}
d1_data = list(d1.items()) d1_data = list(d1.items())
d2_data = list(d2.items()) d2_data = list(d2.items())
for i in range(len(d1)): for i in range(len(d1)):
@@ -24,18 +24,18 @@ def mergedicts(d1, d2):
d1_dict = dict([d1_data_slice]) d1_dict = dict([d1_data_slice])
d2_dict = dict([d2_data_slice]) d2_dict = dict([d2_data_slice])
# merge the dicts # merge the dicts
res.update(d1_dict) res.update(d1_dict) # type: ignore
res.update(d2_dict) res.update(d2_dict) # type: ignore
return res return res
class DataGraph(QtWidgets.QWidget): class DataGraph(QtWidgets.QWidget):
def __init__( def __init__(
self, self,
title, title: str,
data=Union[dict[list, list] | dict[list[dict[str, list]]]], data=Union[dict[list, list], dict[list[dict[str, list[Any]]]]],
generateMissing=False, generateMissing: bool = False,
label=None, label: str = None,
): ):
super().__init__() super().__init__()
log.debug( log.debug(