Document nio_callbacks.py, small code improvements

This commit is contained in:
miruka 2019-12-18 14:24:55 -04:00
parent d9b27eff9f
commit 934d6a79a2
2 changed files with 47 additions and 25 deletions

View File

@ -8,6 +8,8 @@
- Clean up gui test md - Clean up gui test md
- nio ClientTimeout - nio ClientTimeout
- upload delay at the end?
- Handle upload file size limit
- Handle set avatar upload errors - Handle set avatar upload errors
- Confirmation box after picking file to upload - Confirmation box after picking file to upload
- Show real progression for mxc thumbnail loadings - Show real progression for mxc thumbnail loadings
@ -79,6 +81,7 @@
## Interface ## Interface
- Remember ctrl+tab page target
- https://doc.qt.io/qt-5/qml-qtquick-smoothedanimation.html for progress bars - https://doc.qt.io/qt-5/qml-qtquick-smoothedanimation.html for progress bars
- Make all "Cancel" buttons able to cancel running Backend coroutines set - Make all "Cancel" buttons able to cancel running Backend coroutines set
`disabledWhileLoading` to `false` for all "OK" buttons where it makes sense `disabledWhileLoading` to `false` for all "OK" buttons where it makes sense

View File

@ -17,55 +17,74 @@ from .models.items import Account, Room, TypeSpecifier
@dataclass @dataclass
class NioCallbacks: class NioCallbacks:
"""Register callbacks for nio's request responses and room events.
For every nio `Response` and `Event` subclasses, this class can have a
method named `on<ClassName>` (e.g. `onRoomMessageText`) that will
automatically be registered in nio.
For room event content strings, the `%1` and `%2` placeholders
refer to the event's sender and who this event targets (`state_key`).
These are processed from QML, to allow translations of the strings.
"""
client: MatrixClient = field() client: MatrixClient = field()
def __post_init__(self) -> None: def __post_init__(self) -> None:
c = self.client """Register our methods as callbacks."""
for name, class_ in utils.classes_defined_in(nio.responses).items(): for name, class_ in utils.classes_defined_in(nio.responses).items():
with suppress(AttributeError): with suppress(AttributeError):
c.add_response_callback(getattr(self, f"on{name}"), class_) method = getattr(self, f"on{name}")
self.client.add_response_callback(method, class_)
for name, class_ in utils.classes_defined_in(nio.events).items(): for name, class_ in utils.classes_defined_in(nio.events).items():
with suppress(AttributeError): with suppress(AttributeError):
c.add_event_callback(getattr(self, f"on{name}"), class_) method = getattr(self, f"on{name}")
self.client.add_event_callback(method, class_)
c.add_ephemeral_callback( self.client.add_ephemeral_callback(
self.onTypingNoticeEvent, nio.events.TypingNoticeEvent, self.onTypingNoticeEvent, nio.events.TypingNoticeEvent,
) )
async def onSyncResponse(self, resp: nio.SyncResponse) -> None: # Response callbacks
c = self.client
async def onSyncResponse(self, resp: nio.SyncResponse) -> None:
for room_id, info in resp.rooms.join.items(): for room_id, info in resp.rooms.join.items():
if room_id not in c.past_tokens: if room_id not in self.client.past_tokens:
c.past_tokens[room_id] = info.timeline.prev_batch self.client.past_tokens[room_id] = info.timeline.prev_batch
# TODO: way of knowing if a nio.MatrixRoom is left # TODO: way of knowing if a nio.MatrixRoom is left
for room_id, info in resp.rooms.leave.items(): for room_id, info in resp.rooms.leave.items():
# TODO: handle in nio, these are rooms that were left before # TODO: handle in nio, these are rooms that were left before
# starting the client. # starting the client.
if room_id not in c.all_rooms: if room_id not in self.client.all_rooms:
log.warning("Left room not in MatrixClient.rooms: %r", room_id) log.warning("Left room not in MatrixClient.rooms: %r", room_id)
continue continue
# TODO: handle left events in nio async client # TODO: handle left events in nio async client
for ev in info.timeline.events: for ev in info.timeline.events:
if isinstance(ev, nio.RoomMemberEvent): if isinstance(ev, nio.RoomMemberEvent):
await self.onRoomMemberEvent(c.all_rooms[room_id], ev) await self.onRoomMemberEvent(
self.client.all_rooms[room_id], ev,
await c.register_nio_room(c.all_rooms[room_id], left=True)
if not c.first_sync_done.is_set():
self.client.load_rooms_task = asyncio.ensure_future(
c.load_rooms_without_visible_events(),
) )
c.first_sync_done.set() await self.client.register_nio_room(
c.first_sync_date = datetime.now() self.client.all_rooms[room_id], left=True,
c.models[Account][c.user_id].first_sync_done = True )
if not self.client.first_sync_done.is_set():
self.client.load_rooms_task = asyncio.ensure_future(
self.client.load_rooms_without_visible_events(),
)
self.client.first_sync_done.set()
self.client.first_sync_date = datetime.now()
account = self.client.models[Account][self.client.user_id]
account.first_sync_done = True
async def onErrorResponse(self, resp: nio.ErrorResponse) -> None: async def onErrorResponse(self, resp: nio.ErrorResponse) -> None:
@ -76,8 +95,7 @@ class NioCallbacks:
log.warning(repr(resp)) log.warning(repr(resp))
# Callbacks for nio room events # Event callbacks
# Content: %1 is the sender, %2 the target (ev.state_key).
async def onRoomMessageText(self, room, ev) -> None: async def onRoomMessageText(self, room, ev) -> None:
co = HTML_PROCESSOR.filter( co = HTML_PROCESSOR.filter(
@ -178,9 +196,14 @@ class NioCallbacks:
async def process_room_member_event( async def process_room_member_event(
self, room, ev, self, room: nio.MatrixRoom, ev: nio.RoomMemberEvent,
) -> Optional[Tuple[TypeSpecifier, str]]: ) -> Optional[Tuple[TypeSpecifier, str]]:
"""Return a `TypeSpecifier` and string describing a member event.
Matrix member events can represent many actions:
a user joined the room, a user banned another, a user changed their
display name, etc.
"""
if ev.prev_content == ev.content: if ev.prev_content == ev.content:
return None return None
@ -356,14 +379,10 @@ class NioCallbacks:
await self.client.register_nio_event(room, ev, content=co) await self.client.register_nio_event(room, ev, content=co)
# Callbacks for nio invite events
async def onInviteEvent(self, room, ev) -> None: async def onInviteEvent(self, room, ev) -> None:
await self.client.register_nio_room(room) await self.client.register_nio_room(room)
# Callbacks for nio ephemeral events
async def onTypingNoticeEvent(self, room, ev) -> None: async def onTypingNoticeEvent(self, room, ev) -> None:
# Prevent recent past typing notices from being shown for a split # Prevent recent past typing notices from being shown for a split
# second on client startup: # second on client startup: