Get flat SidePane data on Account/Room models sync

QML: Get the data from Python and print it (for now)

Also:
- Remove useless Model.sortable field, all models/items are sortable
- Change SyncId type hint for less mypy complaints
- Remove ModelItem.main_key class attributes, useless since last big
  refactor
This commit is contained in:
miruka 2019-08-17 22:46:54 -04:00
parent 3cc39210b4
commit 4067d8c4ab
8 changed files with 49 additions and 54 deletions

View File

@ -84,6 +84,7 @@ class App:
rl = self.run_in_loop # noqa rl = self.run_in_loop # noqa
ba = self.backend # noqa ba = self.backend # noqa
mo = self.backend.models # noqa mo = self.backend.models # noqa
smo = self.backend.sidepane_model # noqa
cl = self.backend.clients cl = self.backend.clients
tcl = lambda user: cl[f"@test_{user}:matrix.org"] # noqa tcl = lambda user: cl[f"@test_{user}:matrix.org"] # noqa

View File

@ -1,7 +1,7 @@
import asyncio import asyncio
import logging as log import logging as log
import random import random
from typing import DefaultDict, Dict, List, Optional, Tuple, Union from typing import Any, DefaultDict, Dict, List, Optional, Tuple, Union
import hsluv import hsluv
@ -122,6 +122,13 @@ class Backend:
# General functions # General functions
@staticmethod
def hsluv(hue: int, saturation: int, lightness: int) -> List[float]:
# (0-360, 0-100, 0-100) -> [0-1, 0-1, 0-1]
return hsluv.hsluv_to_rgb([hue, saturation, lightness])
async def load_settings(self) -> tuple: async def load_settings(self) -> tuple:
from .config_files import Theme from .config_files import Theme
settings = await self.ui_settings.read() settings = await self.ui_settings.read()
@ -153,7 +160,21 @@ class Backend:
return response return response
@staticmethod async def get_flat_sidepane_data(self) -> List[Dict[str, Any]]:
def hsluv(hue: int, saturation: int, lightness: int) -> List[float]: data = []
# (0-360, 0-100, 0-100) -> [0-1, 0-1, 0-1]
return hsluv.hsluv_to_rgb([hue, saturation, lightness]) for account in sorted(self.models[Account].values()):
data.append({
"type": "Account",
"id": account.user_id,
"data": account.__dict__,
})
for room in sorted(self.models[Room, account.user_id].values()):
data.append({
"type": "Room",
"id": (account.user_id, room.room_id),
"data": room.__dict__,
})
return data

View File

@ -2,5 +2,5 @@ from typing import Tuple, Type, Union
from .model_item import ModelItem from .model_item import ModelItem
# Type[ModelItem] or Tuple[Type[ModelItem], str...] # last one: Tuple[Union[Type[ModelItem], Tuple[Type[ModelItem]]], str...]
SyncId = Union[Type[ModelItem], Tuple[Union[Type[ModelItem], str], ...]] SyncId = Union[Type[ModelItem], Tuple[Type[ModelItem]], tuple]

View File

@ -9,8 +9,6 @@ from .model_item import ModelItem
@dataclass @dataclass
class Account(ModelItem): class Account(ModelItem):
main_key = "user_id"
user_id: str = field() user_id: str = field()
display_name: str = "" display_name: str = ""
avatar_url: str = "" avatar_url: str = ""
@ -24,8 +22,6 @@ class Account(ModelItem):
@dataclass @dataclass
class Room(ModelItem): class Room(ModelItem):
main_key = "room_id"
room_id: str = field() room_id: str = field()
display_name: str = "" display_name: str = ""
avatar_url: str = "" avatar_url: str = ""
@ -66,8 +62,6 @@ class Room(ModelItem):
@dataclass @dataclass
class Member(ModelItem): class Member(ModelItem):
main_key = "user_id"
user_id: str = field() user_id: str = field()
display_name: str = "" display_name: str = ""
avatar_url: str = "" avatar_url: str = ""
@ -89,8 +83,6 @@ class TypeSpecifier(AutoStrEnum):
@dataclass @dataclass
class Event(ModelItem): class Event(ModelItem):
main_key = "event_id"
client_id: str = field() client_id: str = field()
event_id: str = field() event_id: str = field()
event_type: str = field() # Type[nio.Event] event_type: str = field() # Type[nio.Event]
@ -127,8 +119,6 @@ class Event(ModelItem):
@dataclass @dataclass
class Device(ModelItem): class Device(ModelItem):
main_key = "device_id"
device_id: str = field() device_id: str = field()
ed25519_key: str = field() ed25519_key: str = field()
trusted: bool = False trusted: bool = False

View File

@ -1,7 +1,7 @@
import logging as log import logging as log
import time import time
from threading import Lock, Thread from threading import Lock, Thread
from typing import Any, Dict, Iterator, List, MutableMapping, Optional from typing import Any, Dict, Iterator, List, MutableMapping
from . import SyncId from . import SyncId
from ..pyotherside_events import ModelUpdated from ..pyotherside_events import ModelUpdated
@ -11,7 +11,6 @@ from .model_item import ModelItem
class Model(MutableMapping): class Model(MutableMapping):
def __init__(self, sync_id: SyncId) -> None: def __init__(self, sync_id: SyncId) -> None:
self.sync_id: SyncId = sync_id self.sync_id: SyncId = sync_id
self.sortable: Optional[bool] = None
self._data: Dict[Any, ModelItem] = {} self._data: Dict[Any, ModelItem] = {}
self._changed: bool = False self._changed: bool = False
@ -27,22 +26,22 @@ class Model(MutableMapping):
from pprint import pformat # type: ignore from pprint import pformat # type: ignore
if isinstance(self.sync_id, tuple): if isinstance(self.sync_id, tuple):
sid = (self.sync_id[0].__name__, *self.sync_id[1:]) # type: ignore sid = (self.sync_id[0].__name__, *self.sync_id[1:])
else: else:
sid = self.sync_id.__name__ # type: ignore sid = self.sync_id.__name__ # type: ignore
return "%s(sync_id=%s, sortable=%r, %s)" % ( return "%s(sync_id=%s, %s)" % (
type(self).__name__, sid, self.sortable, pformat(self._data), type(self).__name__, sid, pformat(self._data),
) )
def __str__(self) -> str: def __str__(self) -> str:
if isinstance(self.sync_id, tuple): if isinstance(self.sync_id, tuple):
reprs = tuple(repr(s) for s in self.sync_id[1:]) reprs = tuple(repr(s) for s in self.sync_id[1:])
sid = ", ".join((self.sync_id[0].__name__, *reprs)) # type: ignore sid = ", ".join((self.sync_id[0].__name__, *reprs))
sid = f"({sid})" sid = f"({sid})"
else: else:
sid = self.sync_id.__name__ # type: ignore sid = self.sync_id.__name__
return f"{sid!s}: {len(self)} items" return f"{sid!s}: {len(self)} items"
@ -64,7 +63,7 @@ class Model(MutableMapping):
if merged == existing: if merged == existing:
return return
new = type(value)(**merged) # type: ignore new = type(value)(**merged)
new.parent_model = self new.parent_model = self
@ -99,21 +98,8 @@ class Model(MutableMapping):
def serialized(self) -> List[Dict[str, Any]]: def serialized(self) -> List[Dict[str, Any]]:
if self.sortable is True:
return [item.__dict__ for item in sorted(self._data.values())] return [item.__dict__ for item in sorted(self._data.values())]
if self.sortable is False or len(self) < 2:
return [item.__dict__ for item in self._data.values()]
try:
return [item.__dict__ for item in sorted(self._data.values())]
except TypeError:
self.sortable = False
else:
self.sortable = True
return self.serialized()
def __lt__(self, other: "Model") -> bool: def __lt__(self, other: "Model") -> bool:
return str(self.sync_id) < str(other.sync_id) return str(self.sync_id) < str(other.sync_id)

View File

@ -2,15 +2,6 @@ from typing import ClassVar, Optional
class ModelItem: class ModelItem:
main_key: ClassVar[str] = ""
def __init_subclass__(cls) -> None:
if not cls.main_key:
raise ValueError("Must specify main_key str class attribute.")
super().__init_subclass__()
def __new__(cls, *_args, **_kwargs) -> "ModelItem": def __new__(cls, *_args, **_kwargs) -> "ModelItem":
from .model import Model from .model import Model
cls.parent_model: Optional[Model] = None cls.parent_model: Optional[Model] = None

View File

@ -25,7 +25,7 @@ class ModelStore(MutableMapping):
raise ValueError(f"Empty string in key: {key!r}") raise ValueError(f"Empty string in key: {key!r}")
key_type = (key[0],) + \ key_type = (key[0],) + \
tuple(type(el) for el in key[1:]) # type: ignore tuple(type(el) for el in key[1:])
else: else:
key_type = key # type: ignore key_type = key # type: ignore

View File

@ -20,6 +20,12 @@ function onCoroutineDone(uuid, result) {
function onModelUpdated(syncId, data, serializedSyncId) { function onModelUpdated(syncId, data, serializedSyncId) {
if (serializedSyncId == ["Account"] || serializedSyncId[0] == "Room") {
py.callCoro("get_flat_sidepane_data", [], data => {
print( JSON.stringify( data, null, 4))
})
}
window.modelSources[serializedSyncId] = data window.modelSources[serializedSyncId] = data
window.modelSourcesChanged() window.modelSourcesChanged()
} }