Coverage for slidge/core/dispatcher/session_dispatcher.py: 78%
51 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-11-07 05:11 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-11-07 05:11 +0000
1import logging
2from typing import TYPE_CHECKING
4from slixmpp import Message
5from slixmpp.exceptions import IqError, IqTimeout
6from slixmpp.plugins.xep_0084.stanza import Info
8from ..session import BaseSession
9from .caps import CapsMixin
10from .disco import DiscoMixin
11from .message import MessageMixin
12from .muc import MucMixin
13from .presence import PresenceHandlerMixin
14from .registration import RegistrationMixin
15from .search import SearchMixin
16from .util import exceptions_to_xmpp_errors
17from .vcard import VCardMixin
19if TYPE_CHECKING:
20 from slidge.core.gateway import BaseGateway
23class SessionDispatcher(
24 CapsMixin,
25 DiscoMixin,
26 RegistrationMixin,
27 MessageMixin,
28 MucMixin,
29 PresenceHandlerMixin,
30 SearchMixin,
31 VCardMixin,
32):
33 def __init__(self, xmpp: "BaseGateway"):
34 super().__init__(xmpp)
35 xmpp.add_event_handler(
36 "avatar_metadata_publish", self.on_avatar_metadata_publish
37 )
39 @exceptions_to_xmpp_errors
40 async def on_avatar_metadata_publish(self, m: Message):
41 session = await self._get_session(m, timeout=None)
42 if not session.user.preferences.get("sync_avatar", False):
43 session.log.debug("User does not want to sync their avatar")
44 return
45 info = m["pubsub_event"]["items"]["item"]["avatar_metadata"]["info"]
47 await self.on_avatar_metadata_info(session, info)
49 async def on_avatar_metadata_info(self, session: BaseSession, info: Info):
50 hash_ = info["id"]
52 if session.user.avatar_hash == hash_:
53 session.log.debug("We already know this avatar hash")
54 return
55 self.xmpp.store.users.set_avatar_hash(session.user_pk, None)
57 if hash_:
58 try:
59 iq = await self.xmpp.plugin["xep_0084"].retrieve_avatar(
60 session.user_jid, hash_, ifrom=self.xmpp.boundjid.bare
61 )
62 except (IqError, IqTimeout) as e:
63 session.log.warning("Could not fetch the user's avatar: %s", e)
64 return
65 bytes_ = iq["pubsub"]["items"]["item"]["avatar_data"]["value"]
66 type_ = info["type"]
67 height = info["height"]
68 width = info["width"]
69 else:
70 bytes_ = type_ = height = width = hash_ = None
71 try:
72 await session.on_avatar(bytes_, hash_, type_, width, height)
73 except NotImplementedError:
74 pass
75 except Exception as e:
76 # If something goes wrong here, replying an error stanza will to the
77 # avatar update will likely not show in most clients, so let's send
78 # a normal message from the component to the user.
79 session.send_gateway_message(
80 f"Something went wrong trying to set your avatar: {e!r}"
81 )
84log = logging.getLogger(__name__)