Files
devdisc/models.py
2026-06-08 06:17:48 +00:00

769 lines
14 KiB
Python

# v7
from __future__ import annotations
from typing import Any
from dataclasses import dataclass
from pathlib import Path
from PySide6.QtCore import (
QAbstractTableModel,
QModelIndex,
Qt,
)
@dataclass(slots=True)
class ProfileContext:
name: str
root: Path
storage_path: Path
cache_path: Path
downloads_path: Path
plugins_path: Path
themes_path: Path
extensions_path: Path
profile_db: Path
permissions_db: Path
network_db: Path
class NetworkTableModel(
QAbstractTableModel
):
HEADERS = (
"Method",
"Status",
"Host",
"URL",
"Type",
"Duration",
"Timestamp",
)
def __init__(
self,
parent=None,
):
super().__init__(
parent
)
self._rows: list[
dict[str, Any]
] = []
def set_rows(
self,
rows,
) -> None:
self.beginResetModel()
self._rows = [
dict(row)
for row in rows
]
self.endResetModel()
def append_row(
self,
row: dict,
) -> None:
position = len(
self._rows
)
self.beginInsertRows(
QModelIndex(),
position,
position,
)
self._rows.append(
row
)
self.endInsertRows()
def rowCount(
self,
parent=QModelIndex(),
) -> int:
return 0 if parent.isValid() else len(
self._rows
)
def columnCount(
self,
parent=QModelIndex(),
) -> int:
return 0 if parent.isValid() else len(
self.HEADERS
)
def headerData(
self,
section,
orientation,
role,
):
if (
role
!= Qt.ItemDataRole.DisplayRole
):
return None
if (
orientation
== Qt.Orientation.Horizontal
):
if (
0
<= section
< len(
self.HEADERS
)
):
return self.HEADERS[
section
]
return str(
section + 1
)
def data(
self,
index,
role,
):
if (
not index.isValid()
or role
!= Qt.ItemDataRole.DisplayRole
):
return None
row = self._rows[
index.row()
]
match index.column():
case 0:
return row.get(
"method",
"",
)
case 1:
return row.get(
"status_code",
row.get(
"status",
"",
),
)
case 2:
return row.get(
"host",
"",
)
case 3:
return row.get(
"url",
"",
)
case 4:
return row.get(
"resource_type",
"",
)
case 5:
duration = row.get(
"duration_ms"
)
if duration is None:
return ""
try:
return (
f"{float(duration):.2f}"
)
except (
TypeError,
ValueError,
):
return ""
case 6:
return row.get(
"timestamp",
"",
)
return None
def row(
self,
position: int,
) -> dict:
return self._rows[
position
]
class ProfileModel(
QAbstractTableModel
):
HEADERS = (
"Profile",
)
def __init__(
self,
parent=None,
):
super().__init__(
parent
)
self._profiles: list[
str
] = []
def set_profiles(
self,
profiles: list[str],
):
self.beginResetModel()
self._profiles = sorted(
profiles
)
self.endResetModel()
def rowCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else len(
self._profiles
)
def columnCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else 1
def headerData(
self,
section,
orientation,
role,
):
if (
role
!= Qt.ItemDataRole.DisplayRole
):
return None
if (
orientation
== Qt.Orientation.Horizontal
):
return self.HEADERS[
section
]
return None
def data(
self,
index,
role,
):
if (
not index.isValid()
or role
!= Qt.ItemDataRole.DisplayRole
):
return None
return self._profiles[
index.row()
]
class AddonModel(
QAbstractTableModel
):
HEADERS = (
"Name",
"Enabled",
"Type",
)
def __init__(
self,
parent=None,
):
super().__init__(
parent
)
self._addons: list[
dict
] = []
def set_addons(
self,
addons: list[dict],
):
self.beginResetModel()
self._addons = list(
addons
)
self.endResetModel()
def rowCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else len(
self._addons
)
def columnCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else 3
def headerData(
self,
section,
orientation,
role,
):
if (
role
!= Qt.ItemDataRole.DisplayRole
):
return None
if (
orientation
== Qt.Orientation.Horizontal
):
return self.HEADERS[
section
]
return None
def data(
self,
index,
role,
):
if (
not index.isValid()
or role
!= Qt.ItemDataRole.DisplayRole
):
return None
addon = self._addons[
index.row()
]
match index.column():
case 0:
return addon.get(
"name",
"",
)
case 1:
return (
"Yes"
if addon.get(
"enabled",
True,
)
else "No"
)
case 2:
return addon.get(
"type",
"",
)
return None
class PluginTableModel(
QAbstractTableModel
):
HEADERS = (
"Enabled",
"Name",
"Version",
"Author",
"Status",
)
def __init__(
self,
parent=None,
):
super().__init__(
parent
)
self._plugins = []
def set_plugins(
self,
plugins,
):
self.beginResetModel()
self._plugins = [
dict(plugin)
for plugin in plugins
]
self.endResetModel()
def rowCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else len(
self._plugins
)
def columnCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else 5
def headerData(
self,
section,
orientation,
role,
):
if (
role
!= Qt.ItemDataRole.DisplayRole
):
return None
if (
orientation
== Qt.Orientation.Horizontal
):
return self.HEADERS[
section
]
return None
def data(
self,
index,
role,
):
if (
not index.isValid()
or role
!= Qt.ItemDataRole.DisplayRole
):
return None
plugin = self._plugins[
index.row()
]
match index.column():
case 0:
return (
"Yes"
if plugin.get(
"enabled",
True,
)
else "No"
)
case 1:
return plugin.get(
"name",
"",
)
case 2:
return plugin.get(
"version",
"",
)
case 3:
return plugin.get(
"author",
"",
)
case 4:
return plugin.get(
"status",
"Loaded",
)
return None
def row(
self,
position: int,
) -> dict:
return self._plugins[
position
]
class PluginLogTableModel(
QAbstractTableModel
):
HEADERS = (
"Time",
"Plugin",
"Level",
"Message",
)
def __init__(
self,
parent=None,
):
super().__init__(
parent
)
self._rows = []
def set_rows(
self,
rows,
):
self.beginResetModel()
self._rows = [
dict(row)
for row in rows
]
self.endResetModel()
def rowCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else len(
self._rows
)
def columnCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else 4
def headerData(
self,
section,
orientation,
role,
):
if (
role
!= Qt.ItemDataRole.DisplayRole
):
return None
if (
orientation
== Qt.Orientation.Horizontal
):
return self.HEADERS[
section
]
return None
def data(
self,
index,
role,
):
if (
not index.isValid()
or role
!= Qt.ItemDataRole.DisplayRole
):
return None
row = self._rows[
index.row()
]
match index.column():
case 0:
return row.get(
"created_at",
"",
)
case 1:
return row.get(
"plugin_name",
"",
)
case 2:
return row.get(
"level",
"",
)
case 3:
return row.get(
"message",
"",
)
return None
class PluginCrashTableModel(
QAbstractTableModel
):
HEADERS = (
"Time",
"Plugin",
"Error",
)
def __init__(
self,
parent=None,
):
super().__init__(
parent
)
self._rows = []
def set_rows(
self,
rows,
):
self.beginResetModel()
self._rows = [
dict(row)
for row in rows
]
self.endResetModel()
def rowCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else len(
self._rows
)
def columnCount(
self,
parent=QModelIndex(),
):
return 0 if parent.isValid() else 3
def headerData(
self,
section,
orientation,
role,
):
if (
role
!= Qt.ItemDataRole.DisplayRole
):
return None
if (
orientation
== Qt.Orientation.Horizontal
):
return self.HEADERS[
section
]
return None
def data(
self,
index,
role,
):
if (
not index.isValid()
or role
!= Qt.ItemDataRole.DisplayRole
):
return None
row = self._rows[
index.row()
]
match index.column():
case 0:
return row.get(
"created_at",
"",
)
case 1:
return row.get(
"plugin_name",
"",
)
case 2:
return row.get(
"error",
"",
)
return None