Add Backend.devices ListModelMap
The Device ListModels will be populated after login.
This commit is contained in:
parent
a15f6b0bac
commit
1a90bb4331
9
TODO.md
9
TODO.md
|
@ -71,3 +71,12 @@
|
|||
- Distribution
|
||||
- Review setup.py, add dependencies
|
||||
- README.md
|
||||
- Use PyInstaller or pyqtdeploy
|
||||
- Test command:
|
||||
```
|
||||
pyinstaller --onefile --windowed --name harmonyqml \
|
||||
--add-data 'harmonyqml/components:harmonyqml/components' \
|
||||
--additional-hooks-dir . \
|
||||
--upx-dir ~/opt/upx-3.95-amd64_linux \
|
||||
run.py
|
||||
```
|
||||
|
|
|
@ -30,6 +30,7 @@ class Backend(QObject):
|
|||
|
||||
self._accounts: ListModel = ListModel(parent=parent)
|
||||
self._room_events: ListModelMap = ListModelMap(Deque, parent)
|
||||
self._devices: ListModelMap = ListModelMap(parent=parent)
|
||||
|
||||
from .signal_manager import SignalManager
|
||||
self._signal_manager: SignalManager = SignalManager(self)
|
||||
|
@ -53,6 +54,10 @@ class Backend(QObject):
|
|||
def roomEvents(self):
|
||||
return self._room_events
|
||||
|
||||
@pyqtProperty("QVariant", constant=True)
|
||||
def devices(self):
|
||||
return self._devices
|
||||
|
||||
@pyqtProperty("QVariant", constant=True)
|
||||
def signals(self):
|
||||
return self._signal_manager
|
||||
|
@ -141,6 +146,7 @@ class Backend(QObject):
|
|||
cl = self.clients
|
||||
ac = self.accounts
|
||||
re = self.roomEvents
|
||||
de = self.devices
|
||||
|
||||
tcl = lambda user: cl[f"@test_{user}:matrix.org"]
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ from PyQt5.QtCore import (
|
|||
|
||||
import nio
|
||||
|
||||
from .model.items import Trust
|
||||
from .network_manager import NetworkManager
|
||||
from .pyqt_future import PyQtFuture, futurize
|
||||
|
||||
|
@ -81,19 +82,19 @@ class Client(QObject):
|
|||
|
||||
|
||||
@futurize(max_running=1, discard_if_max_running=True, pyqt=False)
|
||||
def _keys_upload(self) -> None:
|
||||
def uploadE2EKeys(self) -> None:
|
||||
self.net.talk(self.nio.keys_upload)
|
||||
|
||||
|
||||
def _keys_query(self) -> None:
|
||||
def queryE2EKeys(self) -> None:
|
||||
self.net.talk(self.nio.keys_query)
|
||||
|
||||
|
||||
def _keys_claim(self, room_id: str) -> None:
|
||||
def claimE2EKeysForRoom(self, room_id: str) -> None:
|
||||
self.net.talk(self.nio.keys_claim, room_id)
|
||||
|
||||
|
||||
def _share_group_session(self,
|
||||
def shareRoomE2ESession(self,
|
||||
room_id: str,
|
||||
ignore_missing_sessions: bool = False) -> None:
|
||||
self.net.talk(
|
||||
|
@ -103,16 +104,21 @@ class Client(QObject):
|
|||
)
|
||||
|
||||
|
||||
def getDeviceTrust(self, device: nio.crypto.OlmDevice) -> Trust:
|
||||
olm = self.nio.olm
|
||||
return (
|
||||
Trust.trusted if olm.is_device_verified(device) else
|
||||
Trust.blacklisted if olm.is_device_blacklisted(device) else
|
||||
Trust.undecided
|
||||
)
|
||||
|
||||
|
||||
@pyqtSlot(str, result="QVariant")
|
||||
@pyqtSlot(str, str, result="QVariant")
|
||||
@futurize()
|
||||
def login(self, password: str, device_name: str = "") -> "Client":
|
||||
response = self.net.talk(self.nio.login, password, device_name)
|
||||
self.nio_sync.receive_response(response)
|
||||
|
||||
if not self.nio.olm_account_shared:
|
||||
self._keys_upload()
|
||||
|
||||
return self
|
||||
|
||||
|
||||
|
@ -123,10 +129,6 @@ class Client(QObject):
|
|||
response = nio.LoginResponse(user_id, device_id, token)
|
||||
self.nio.receive_response(response)
|
||||
self.nio_sync.receive_response(response)
|
||||
|
||||
if not self.nio.olm_account_shared:
|
||||
self._keys_upload()
|
||||
|
||||
return self
|
||||
|
||||
|
||||
|
@ -158,10 +160,10 @@ class Client(QObject):
|
|||
self.nio.receive_response(response)
|
||||
|
||||
if self.nio.should_upload_keys:
|
||||
self._keys_upload()
|
||||
self.uploadE2EKeys()
|
||||
|
||||
if self.nio.should_query_keys:
|
||||
self._keys_query()
|
||||
self.queryE2EKeys()
|
||||
|
||||
for room_id, room_info in response.rooms.invite.items():
|
||||
for ev in room_info.invite_state:
|
||||
|
@ -280,11 +282,11 @@ class Client(QObject):
|
|||
except nio.GroupEncryptionError as err:
|
||||
log.warning(err)
|
||||
try:
|
||||
self._share_group_session(room_id)
|
||||
self.shareRoomE2ESession(room_id)
|
||||
except nio.EncryptionError as err:
|
||||
log.warning(err)
|
||||
self._keys_claim(room_id)
|
||||
self._share_group_session(room_id,
|
||||
self.claimE2EKeysForRoom(room_id)
|
||||
self.shareRoomE2ESession(room_id,
|
||||
ignore_missing_sessions=True)
|
||||
|
||||
log.debug("Final try to send %r to %r", content, room_id)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from enum import Enum
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from PyQt5.QtCore import QDateTime, QSortFilterProxyModel
|
||||
|
@ -42,6 +43,22 @@ class RoomCategory(ListItem):
|
|||
sortedRooms: QSortFilterProxyModel = QSortFilterProxyModel()
|
||||
|
||||
|
||||
class Trust(Enum):
|
||||
blacklisted = -1
|
||||
undecided = 0
|
||||
trusted = 1
|
||||
|
||||
|
||||
class Device(ListItem):
|
||||
_required_init_values = {"deviceId", "ed25519Key"}
|
||||
_constant = {"deviceId", "ed25519Key"}
|
||||
|
||||
deviceId: str = ""
|
||||
ed25519Key: str = ""
|
||||
displayName: Optional[str] = None
|
||||
trust: Trust = Trust.undecided
|
||||
|
||||
|
||||
class Account(ListItem):
|
||||
_required_init_values = {"userId", "roomCategories"}
|
||||
_constant = {"userId", "roomCategories"}
|
||||
|
|
|
@ -11,7 +11,9 @@ from nio.rooms import MatrixRoom
|
|||
|
||||
from .backend import Backend
|
||||
from .client import Client
|
||||
from .model.items import Account, ListModel, Room, RoomCategory, RoomEvent
|
||||
from .model.items import (
|
||||
Account, Device, ListModel, Room, RoomCategory, RoomEvent
|
||||
)
|
||||
from .model.sort_filter_proxy import SortFilterProxy
|
||||
|
||||
Inviter = Optional[Dict[str, str]]
|
||||
|
@ -35,8 +37,7 @@ class SignalManager(QObject):
|
|||
|
||||
|
||||
def onClientAdded(self, client: Client) -> None:
|
||||
self.connectClient(client)
|
||||
|
||||
# Build an Account item for the Backend.accounts model
|
||||
room_categories_kwargs: List[Dict[str, Any]] = [
|
||||
{"name": "Invites", "rooms": ListModel()},
|
||||
{"name": "Rooms", "rooms": ListModel()},
|
||||
|
@ -59,6 +60,27 @@ class SignalManager(QObject):
|
|||
displayName = self.backend.getUserDisplayName(client.userId),
|
||||
))
|
||||
|
||||
# Upload our E2E keys to the matrix server if needed
|
||||
if not client.nio.olm_account_shared:
|
||||
client.uploadE2EKeys()
|
||||
|
||||
# Add our devices to the Backend.devices model
|
||||
store = client.nio.device_store
|
||||
|
||||
for user_id in store.users:
|
||||
self.backend.devices[user_id].clear()
|
||||
self.backend.devices[user_id].extend([
|
||||
Device(
|
||||
deviceId = dev.id,
|
||||
ed25519Key = dev.ed25519,
|
||||
trust = client.getDeviceTrust(dev),
|
||||
# displayName = TODO
|
||||
) for dev in store.active_user_devices(user_id)
|
||||
])
|
||||
|
||||
# Finally, connect all client signals
|
||||
self.connectClient(client)
|
||||
|
||||
|
||||
def onClientDeleted(self, user_id: str) -> None:
|
||||
del self.backend.accounts[user_id]
|
||||
|
|
Loading…
Reference in New Issue
Block a user