annotate libervia/backend/plugins/plugin_xep_0084.py @ 4118:07370d2a9bde

plugin XEP-0167: keep media order when starting a call: media content order is relevant when building Jingle contents/SDP notably for bundling. This patch fixes the previous behaviour of always using the same order by keeping the order of the data (i.e. order of original SDP offer). Previous behaviour could lead to call failure. rel 424
author Goffi <goffi@goffi.org>
date Tue, 03 Oct 2023 15:15:24 +0200
parents 4b842c1fb686
children 0d7bb4df2343
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia plugin for XEP-0084
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2022 Jérôme Poisson (goffi@goffi.org)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 from typing import Optional, Dict, Any
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 from pathlib import Path
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from base64 import b64decode, b64encode
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
22
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from twisted.internet import defer
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from twisted.words.protocols.jabber import jid, error
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from twisted.words.xish import domish
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from zope.interface import implementer
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 from wokkel import disco, iwokkel, pubsub
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
29
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
30 from libervia.backend.core.constants import Const as C
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
31 from libervia.backend.core.i18n import _
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
32 from libervia.backend.core.log import getLogger
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
33 from libervia.backend.core.core_types import SatXMPPEntity
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
34 from libervia.backend.core import exceptions
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
35
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
36
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 log = getLogger(__name__)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 IMPORT_NAME = "XEP-0084"
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
40
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 PLUGIN_INFO = {
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 C.PI_NAME: "User Avatar",
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 C.PI_IMPORT_NAME: IMPORT_NAME,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 C.PI_TYPE: C.PLUG_TYPE_XEP,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 C.PI_MODES: C.PLUG_MODE_BOTH,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 C.PI_PROTOCOLS: ["XEP-0084"],
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 C.PI_DEPENDENCIES: ["IDENTITY", "XEP-0060", "XEP-0163"],
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 C.PI_MAIN: "XEP_0084",
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 C.PI_HANDLER: "yes",
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 C.PI_DESCRIPTION: _("""XEP-0084 (User Avatar) implementation"""),
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 }
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
52
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 NS_AVATAR = "urn:xmpp:avatar"
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 NS_AVATAR_METADATA = f"{NS_AVATAR}:metadata"
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 NS_AVATAR_DATA = f"{NS_AVATAR}:data"
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
56
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
57
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 class XEP_0084:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 namespace_metadata = NS_AVATAR_METADATA
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 namespace_data = NS_AVATAR_DATA
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
61
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 def __init__(self, host):
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 log.info(_("XEP-0084 (User Avatar) plugin initialization"))
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
64 host.register_namespace("avatar_metadata", NS_AVATAR_METADATA)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
65 host.register_namespace("avatar_data", NS_AVATAR_DATA)
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 self.host = host
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 self._p = host.plugins["XEP-0060"]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 self._i = host.plugins['IDENTITY']
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 self._i.register(
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 IMPORT_NAME,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 "avatar",
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
72 self.get_avatar,
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
73 self.set_avatar,
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 priority=2000
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
76 host.plugins["XEP-0163"].add_pep_event(
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
77 None, NS_AVATAR_METADATA, self._on_metadata_update
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 )
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
79
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
80 def get_handler(self, client):
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 return XEP_0084_Handler()
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
82
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
83 def _on_metadata_update(self, itemsEvent, profile):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
84 client = self.host.get_client(profile)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
85 defer.ensureDeferred(self.on_metadata_update(client, itemsEvent))
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
86
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
87 async def on_metadata_update(
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 self,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 client: SatXMPPEntity,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 itemsEvent: pubsub.ItemsEvent
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 ) -> None:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 entity = client.jid.userhostJID()
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
93 avatar_metadata = await self.get_avatar(client, entity)
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 await self._i.update(client, IMPORT_NAME, "avatar", avatar_metadata, entity)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
95
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
96 async def get_avatar(
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 self,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 client: SatXMPPEntity,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 entity_jid: jid.JID
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 ) -> Optional[dict]:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 """Get avatar data
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
102
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 @param entity: entity to get avatar from
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 @return: avatar metadata, or None if no avatar has been found
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 """
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 service = entity_jid.userhostJID()
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 # metadata
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
109 items, __ = await self._p.get_items(
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 client,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 service,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
112 NS_AVATAR_METADATA,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 max_items=1
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 )
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 except exceptions.NotFound:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 return None
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
117
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 if not items:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 return None
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
120
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 item_elt = items[0]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 try:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 metadata_elt = next(item_elt.elements(NS_AVATAR_METADATA, "metadata"))
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 except StopIteration:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 log.warning(f"missing metadata element: {item_elt.toXml()}")
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 return None
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
127
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 for info_elt in metadata_elt.elements(NS_AVATAR_METADATA, "info"):
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 try:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 metadata = {
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 "id": str(info_elt["id"]),
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 "size": int(info_elt["bytes"]),
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 "media_type": str(info_elt["type"])
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
134 }
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
135 avatar_id = metadata["id"]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 if not avatar_id:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 raise ValueError
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 except (KeyError, ValueError):
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
139 log.warning(f"invalid <info> element: {item_elt.toXml()}")
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 return None
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 # FIXME: to simplify, we only handle image/png for now
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 if metadata["media_type"] == "image/png":
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 break
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 else:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
145 # mandatory image/png is missing, or avatar is disabled
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 # (https://xmpp.org/extensions/xep-0084.html#pub-disable)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 return None
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
148
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
149 cache_data = self.host.common_cache.get_metadata(avatar_id)
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 if not cache_data:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
152 data_items, __ = await self._p.get_items(
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 client,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 service,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
155 NS_AVATAR_DATA,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
156 item_ids=[avatar_id]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
157 )
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 data_item_elt = data_items[0]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 except (error.StanzaError, IndexError) as e:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
160 log.warning(
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 f"Can't retrieve avatar of {service.full()} with ID {avatar_id!r}: "
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 f"{e}"
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 )
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 return None
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 try:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
166 avatar_buf = b64decode(
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 str(next(data_item_elt.elements(NS_AVATAR_DATA, "data")))
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 )
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 except Exception as e:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 log.warning(
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 f"invalid data element for {service.full()} with avatar ID "
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 f"{avatar_id!r}: {e}\n{data_item_elt.toXml()}"
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 )
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 return None
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
175 with self.host.common_cache.cache_data(
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 IMPORT_NAME,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 avatar_id,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 metadata["media_type"]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 ) as f:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 f.write(avatar_buf)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 cache_data = {
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 "path": Path(f.name),
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 "mime_type": metadata["media_type"]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 }
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
185
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
186 return self._i.avatar_build_metadata(
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 cache_data['path'], cache_data['mime_type'], avatar_id
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 )
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
189
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
190 def build_item_data_elt(self, avatar_data: Dict[str, Any]) -> domish.Element:
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 """Generate the item for the data node
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
192
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 @param avatar_data: data as build by identity plugin (need to be filled with
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 "cache_uid" and "base64" keys)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 """
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 data_elt = domish.Element((NS_AVATAR_DATA, "data"))
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 data_elt.addContent(avatar_data["base64"])
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 return pubsub.Item(id=avatar_data["cache_uid"], payload=data_elt)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
199
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
200 def build_item_metadata_elt(self, avatar_data: Dict[str, Any]) -> domish.Element:
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 """Generate the item for the metadata node
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
202
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 @param avatar_data: data as build by identity plugin (need to be filled with
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 "cache_uid", "path", and "media_type" keys)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 """
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 metadata_elt = domish.Element((NS_AVATAR_METADATA, "metadata"))
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 info_elt = metadata_elt.addElement("info")
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 # FIXME: we only fill required elements for now (see
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 # https://xmpp.org/extensions/xep-0084.html#table-1)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 info_elt["id"] = avatar_data["cache_uid"]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 info_elt["type"] = avatar_data["media_type"]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 info_elt["bytes"] = str(avatar_data["path"].stat().st_size)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 return pubsub.Item(id=self._p.ID_SINGLETON, payload=metadata_elt)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
214
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
215 async def set_avatar(
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 self,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 client: SatXMPPEntity,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 avatar_data: Dict[str, Any],
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 entity: jid.JID
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 ) -> None:
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 """Set avatar of the profile
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
222
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 @param avatar_data(dict): data of the image to use as avatar, as built by
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 IDENTITY plugin.
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
225 @param entity(jid.JID): entity whose avatar must be changed
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 """
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 service = entity.userhostJID()
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
228
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 # Data
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
230 await self._p.create_if_new_node(
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 client,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 service,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 NS_AVATAR_DATA,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 options={
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 self._p.OPT_PERSIST_ITEMS: 1,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 self._p.OPT_MAX_ITEMS: 1,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 }
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
240 item_data_elt = self.build_item_data_elt(avatar_data)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
241 await self._p.send_items(client, service, NS_AVATAR_DATA, [item_data_elt])
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
242
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 # Metadata
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
244 await self._p.create_if_new_node(
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 client,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
246 service,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 NS_AVATAR_METADATA,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
248 options={
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
250 self._p.OPT_PERSIST_ITEMS: 1,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
251 self._p.OPT_MAX_ITEMS: 1,
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 }
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
253 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
254 item_metadata_elt = self.build_item_metadata_elt(avatar_data)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3820
diff changeset
255 await self._p.send_items(client, service, NS_AVATAR_METADATA, [item_metadata_elt])
3820
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
256
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
257
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 @implementer(iwokkel.IDisco)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 class XEP_0084_Handler(XMPPHandler):
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
260
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
261 def getDiscoInfo(self, requestor, service, nodeIdentifier=""):
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
262 return [
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 disco.DiscoFeature(NS_AVATAR_METADATA),
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 disco.DiscoFeature(NS_AVATAR_DATA)
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 ]
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
266
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
267 def getDiscoItems(self, requestor, service, nodeIdentifier=""):
88e332cec47b plugin XEP-0084: "User Avatar" implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 return []