769 lines
14 KiB
Python
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
|