Make clientManager easier to use

- Backend.clientManager renamed to Backend.clients
- clientManager is now a Mapping subclass

Before/After from Python:
backend.clientManager.clients[thing] → backend.clients[thing]

From QML:
Backend.clientManager.clients[thing] → Backend.clients.get(thing)
This commit is contained in:
miruka 2019-05-02 14:54:37 -04:00
parent 52d538e995
commit 51386821bc
10 changed files with 53 additions and 44 deletions

View File

@ -32,7 +32,7 @@ class Backend(QObject):
from .signal_manager import SignalManager from .signal_manager import SignalManager
self._signal_manager: SignalManager = SignalManager(self) self._signal_manager: SignalManager = SignalManager(self)
self.clientManager.configLoad() self.clients.configLoad()
@pyqtProperty("QVariant", constant=True) @pyqtProperty("QVariant", constant=True)
@ -40,7 +40,7 @@ class Backend(QObject):
return self._html_filter return self._html_filter
@pyqtProperty("QVariant", constant=True) @pyqtProperty("QVariant", constant=True)
def clientManager(self): def clients(self):
return self._client_manager return self._client_manager
@pyqtProperty("QVariant", constant=True) @pyqtProperty("QVariant", constant=True)
@ -59,7 +59,7 @@ class Backend(QObject):
if user_id in self._queried_displaynames: if user_id in self._queried_displaynames:
return self._queried_displaynames[user_id] return self._queried_displaynames[user_id]
for client in self.clientManager.clients.values(): for client in self.clients.values():
for room in client.nio.rooms.values(): for room in client.nio.rooms.values():
displayname = room.user_name(user_id) displayname = room.user_name(user_id)
@ -70,7 +70,7 @@ class Backend(QObject):
def _query_user_displayname(self, user_id: str) -> str: def _query_user_displayname(self, user_id: str) -> str:
client = next(iter(self.clientManager.clients.values())) client = next(iter(self.clients.values()))
response = client.net.talk(client.nio.get_displayname, user_id) response = client.net.talk(client.nio.get_displayname, user_id)
displayname = getattr(response, "displayname", "") or user_id displayname = getattr(response, "displayname", "") or user_id
@ -93,7 +93,7 @@ class Backend(QObject):
if room_id in self.fully_loaded_rooms: if room_id in self.fully_loaded_rooms:
return return
for client in self.clientManager.clients.values(): for client in self.clients.values():
if room_id in client.nio.rooms: if room_id in client.nio.rooms:
client.loadPastEvents( client.loadPastEvents(
room_id, self.past_tokens[room_id], limit room_id, self.past_tokens[room_id], limit
@ -105,12 +105,11 @@ class Backend(QObject):
@pyqtSlot(list) @pyqtSlot(list)
def pdb(self, additional_data: Sequence = ()) -> None: def pdb(self, additional_data: Sequence = ()) -> None:
# pylint: disable=all # pylint: disable=all
ad = additional_data a = additional_data
cm = self.clientManager c = self.clients
cl = self.clientManager.clients m = self.models
m = self.models
tcl = lambda user: cl[f"@test_{user}:matrix.org"] tcl = lambda user: c[f"@test_{user}:matrix.org"]
import pdb import pdb
from PyQt5.QtCore import pyqtRemoveInputHook from PyQt5.QtCore import pyqtRemoveInputHook

View File

@ -5,7 +5,8 @@ import json
import os import os
import platform import platform
import threading import threading
from typing import Dict, Optional from collections.abc import Mapping
from typing import Dict, Iterable, Optional
from atomicfile import AtomicFile from atomicfile import AtomicFile
from PyQt5.QtCore import ( from PyQt5.QtCore import (
@ -22,7 +23,11 @@ AccountConfig = Dict[str, Dict[str, str]]
_CONFIG_LOCK = threading.Lock() _CONFIG_LOCK = threading.Lock()
class ClientManager(QObject): class _ClientManagerMeta(type(QObject), type(Mapping)): # type: ignore
pass
class ClientManager(QObject, Mapping, metaclass=_ClientManagerMeta):
clientAdded = pyqtSignal(Client) clientAdded = pyqtSignal(Client)
clientDeleted = pyqtSignal(str) clientDeleted = pyqtSignal(str)
clientCountChanged = pyqtSignal(int) clientCountChanged = pyqtSignal(int)
@ -33,23 +38,35 @@ class ClientManager(QObject):
self.backend = backend self.backend = backend
self._clients: Dict[str, Client] = {} self._clients: Dict[str, Client] = {}
func = lambda: self.clientCountChanged.emit(len(self.clients)) func = lambda: self.clientCountChanged.emit(len(self))
self.clientAdded.connect(func) self.clientAdded.connect(func)
self.clientDeleted.connect(func) self.clientDeleted.connect(func)
def __repr__(self) -> str: def __repr__(self) -> str:
return f"{type(self).__name__}(clients={self.clients!r})" return f"{type(self).__name__}(clients={self._clients!r})"
@pyqtProperty("QVariantMap", notify=clientCountChanged) def __getitem__(self, user_id: str) -> Client:
def clients(self): return self.get(user_id)
return self._clients
def __len__(self) -> int:
return self.count
def __iter__(self):
return iter(self._clients)
@pyqtSlot(str, result="QVariant")
def get(self, key: str) -> Client:
return self._clients[key]
@pyqtProperty(int, notify=clientCountChanged) @pyqtProperty(int, notify=clientCountChanged)
def clientCount(self): def count(self):
return len(self.clients) return len(self._clients)
@pyqtSlot() @pyqtSlot()
@ -72,23 +89,23 @@ class ClientManager(QObject):
def _on_connected(self, client: Client) -> None: def _on_connected(self, client: Client) -> None:
self.clients[client.userId] = client self._clients[client.userId] = client
self.clientAdded.emit(client) self.clientAdded.emit(client)
client.startSyncing() client.startSyncing()
@pyqtSlot(str) @pyqtSlot(str)
def delete(self, user_id: str) -> None: def remove(self, user_id: str) -> None:
client = self.clients.pop(user_id, None) client = self._clients.pop(user_id, None)
if client: if client:
self.clientDeleted.emit(user_id) self.clientDeleted.emit(user_id)
client.logout() client.logout()
@pyqtSlot() @pyqtSlot()
def deleteAll(self) -> None: def removeAll(self) -> None:
for user_id in self.clients.copy(): for user_id in self._clients.copy():
self.delete(user_id) self.remove(user_id)
@pyqtProperty(str, constant=True) @pyqtProperty(str, constant=True)

View File

@ -27,9 +27,8 @@ class SignalManager(QObject):
self.last_room_events: Deque[str] = Deque(maxlen=1000) self.last_room_events: Deque[str] = Deque(maxlen=1000)
self._events_in_transfer: int = 0 self._events_in_transfer: int = 0
cm = self.backend.clientManager self.backend.clients.clientAdded.connect(self.onClientAdded)
cm.clientAdded.connect(self.onClientAdded) self.backend.clients.clientDeleted.connect(self.onClientDeleted)
cm.clientDeleted.connect(self.onClientDeleted)
def onClientAdded(self, client: Client) -> None: def onClientAdded(self, client: Client) -> None:
@ -161,7 +160,7 @@ class SignalManager(QObject):
event_is_our_profile_changed = ( event_is_our_profile_changed = (
etype == "RoomMemberEvent" and etype == "RoomMemberEvent" and
edict.get("sender") in self.backend.clientManager.clients and edict.get("sender") in self.backend.clients and
((edict.get("content") or {}).get("membership") == ((edict.get("content") or {}).get("membership") ==
(edict.get("prev_content") or {}).get("membership")) (edict.get("prev_content") or {}).get("membership"))
) )

View File

@ -30,16 +30,12 @@ Banner {
buttonCallbacks: { buttonCallbacks: {
"accept": function(button) { "accept": function(button) {
button.loading = true button.loading = true
Backend.clientManager.clients[chatPage.userId].joinRoom( Backend.clients.get(chatPage.userId).joinRoom(chatPage.roomId)
chatPage.roomId
)
}, },
"decline": function(button) { "decline": function(button) {
button.loading = true button.loading = true
Backend.clientManager.clients[chatPage.userId].leaveRoom( Backend.clients.get(chatPage.userId).leaveRoom(chatPage.roomId)
chatPage.roomId
)
} }
} }
} }

View File

@ -22,9 +22,7 @@ Banner {
"forget": function(button) { "forget": function(button) {
button.loading = true button.loading = true
chatPage.canLoadPastEvents = false chatPage.canLoadPastEvents = false
Backend.clientManager.clients[chatPage.userId].forgetRoom( Backend.clients.get(chatPage.userId).forgetRoom(chatPage.roomId)
chatPage.roomId
)
pageStack.clear() pageStack.clear()
}, },
} }

View File

@ -32,7 +32,7 @@ HGlassRectangle {
area.focus: true area.focus: true
function setTyping(typing) { function setTyping(typing) {
Backend.clientManager.clients[chatPage.userId] Backend.clients.get(chatPage.userId)
.setTypingState(chatPage.roomId, typing) .setTypingState(chatPage.roomId, typing)
} }
@ -50,7 +50,7 @@ HGlassRectangle {
} }
if (textArea.text === "") { return } if (textArea.text === "") { return }
Backend.clientManager.clients[chatPage.userId] Backend.clients.get(chatPage.userId)
.sendMarkdown(chatPage.roomId, textArea.text) .sendMarkdown(chatPage.roomId, textArea.text)
textArea.clear() textArea.clear()
} }

View File

@ -20,7 +20,7 @@ Item {
buttonCallbacks: { buttonCallbacks: {
"yes": function(button) { "yes": function(button) {
Backend.clientManager.remember(client) Backend.clients.remember(client)
pageStack.showPage("Default") pageStack.showPage("Default")
}, },
"no": function(button) { pageStack.showPage("Default") }, "no": function(button) { pageStack.showPage("Default") },

View File

@ -23,7 +23,7 @@ Item {
"register": function(button) {}, "register": function(button) {},
"login": function(button) { "login": function(button) {
var future = Backend.clientManager.new( var future = Backend.clients.new(
"matrix.org", identifierField.text, passwordField.text "matrix.org", identifierField.text, passwordField.text
) )
button.loadingUntilFutureDone(future) button.loadingUntilFutureDone(future)

View File

@ -17,7 +17,7 @@ Item {
anchors.fill: parent anchors.fill: parent
} }
property bool accountsLoggedIn: Backend.clientManager.clientCount > 0 property bool accountsLoggedIn: Backend.clients.count > 0
HSplitView { HSplitView {
anchors.fill: parent anchors.fill: parent

View File

@ -8,7 +8,7 @@ ApplicationWindow {
width: Math.min(Screen.width, 1152) width: Math.min(Screen.width, 1152)
height: Math.min(Screen.height, 768) height: Math.min(Screen.height, 768)
onClosing: Backend.clientManager.deleteAll() onClosing: Backend.clients.removeAll()
Loader { Loader {
anchors.fill: parent anchors.fill: parent