annotate sat/plugins/plugin_xep_0054.py @ 3405:ecdb3728749e

plugin XEP-0353: Jingle Message Initiation implementation: This plugin uses the new `XEP-0166_initiate` trigger to initiate a Jingle session with messages if the peer jid has no resource specified. On reception, if the sender is not in our roster, a confirmation is requested to user to avoid leaking presence and IP. If user refuses the session for somebody not in roster, nothing is sent at all (the request is just ignored).
author Goffi <goffi@goffi.org>
date Thu, 12 Nov 2020 14:53:15 +0100
parents 9e1ba1e1179f
children be6d91572633
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
1 #!/usr/bin/env python3
3137
559a625a236b fixed shebangs
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
2
609
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
3 # SAT plugin for managing xep-0054
3136
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3040
diff changeset
4 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org)
788
d6652683c572 plugin XEP-0054: also work with python2-pillow
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 771
diff changeset
5 # Copyright (C) 2014 Emmanuel Gil Peyrot (linkmauve@linkmauve.fr)
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
6
609
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
7 # This program is free software: you can redistribute it and/or modify
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
10 # (at your option) any later version.
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
11
609
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
12 # This program is distributed in the hope that it will be useful,
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
15 # GNU Affero General Public License for more details.
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
16
609
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
84a6e83157c2 fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents: 594
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
19
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
20 import io
3185
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
21 from base64 import b64decode, b64encode
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
22 from hashlib import sha1
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
23 from pathlib import Path
3279
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
24 from typing import Optional
3185
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
25 from zope.interface import implementer
939
01342bfe9f41 wix: fixed onShowProfile
Goffi <goffi@goffi.org>
parents: 916
diff changeset
26 from twisted.internet import threads, defer
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
27 from twisted.words.protocols.jabber import jid, error
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
28 from twisted.words.xish import domish
765
787ee59dba9c plugins radiocol, xep-0054: better handling of upload errors:
souliane <souliane@mailoo.org>
parents: 639
diff changeset
29 from twisted.python.failure import Failure
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from wokkel import disco, iwokkel
3185
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
31 from sat.core import exceptions
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
32 from sat.core.i18n import _
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
33 from sat.core.constants import Const as C
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
34 from sat.core.log import getLogger
3279
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
35 from sat.core.xmpp import SatXMPPEntity
3185
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
36 from sat.memory import persistent
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
37 from sat.tools import image
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
38
3185
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
39 log = getLogger(__name__)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
40
1542
94901070478e plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents: 1437
diff changeset
41 try:
94901070478e plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents: 1437
diff changeset
42 from PIL import Image
94901070478e plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents: 1437
diff changeset
43 except:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
44 raise exceptions.MissingModule(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
45 "Missing module pillow, please download/install it from https://python-pillow.github.io"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
46 )
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
47
48
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
48 try:
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
49 from twisted.words.protocols.xmlstream import XMPPHandler
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
50 except ImportError:
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
51 from wokkel.subprotocols import XMPPHandler
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
52
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
53 IMPORT_NAME = "XEP-0054"
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
54
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
55 PLUGIN_INFO = {
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
56 C.PI_NAME: "XEP 0054 Plugin",
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
57 C.PI_IMPORT_NAME: IMPORT_NAME,
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
58 C.PI_TYPE: "XEP",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
59 C.PI_PROTOCOLS: ["XEP-0054", "XEP-0153"],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
60 C.PI_DEPENDENCIES: ["IDENTITY"],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
61 C.PI_RECOMMENDATIONS: [],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
62 C.PI_MAIN: "XEP_0054",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
63 C.PI_HANDLER: "yes",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
64 C.PI_DESCRIPTION: _("""Implementation of vcard-temp"""),
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
65 }
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
66
365
efbfccfed623 core: local_dir moved to config file
Goffi <goffi@goffi.org>
parents: 291
diff changeset
67 AVATAR_PATH = "avatars"
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
68 AVATAR_DIM = (128, 128)
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
69
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
70 IQ_GET = '/iq[@type="get"]'
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
71 NS_VCARD = "vcard-temp"
594
e629371a28d3 Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 588
diff changeset
72 VCARD_REQUEST = IQ_GET + '/vCard[@xmlns="' + NS_VCARD + '"]' # TODO: manage requests
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
73
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
74 PRESENCE = "/presence"
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
75 NS_VCARD_UPDATE = "vcard-temp:x:update"
594
e629371a28d3 Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 588
diff changeset
76 VCARD_UPDATE = PRESENCE + '/x[@xmlns="' + NS_VCARD_UPDATE + '"]'
48
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
77
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
78 HASH_SHA1_EMPTY = "da39a3ee5e6b4b0d3255bfef95601890afd80709"
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
79
594
e629371a28d3 Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 588
diff changeset
80
588
beaf6bec2fcd Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 587
diff changeset
81 class XEP_0054(object):
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
82
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
83 def __init__(self, host):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
84 log.info(_("Plugin XEP_0054 initialization"))
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
85 self.host = host
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
86 self._i = host.plugins['IDENTITY']
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
87 self._i.register(IMPORT_NAME, 'avatar', self.getAvatar, self.setAvatar)
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
88 self._i.register(IMPORT_NAME, 'nicknames', self.getNicknames, self.setNicknames)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
89 host.trigger.add("presence_available", self.presenceAvailableTrigger)
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
90
2144
1d3f73e065e1 core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents: 2123
diff changeset
91 def getHandler(self, client):
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
92 return XEP_0054_handler(self)
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
93
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
94 def presenceAvailableTrigger(self, presence_elt, client):
1710
7226280e70da plugin XEP-0054: use full jid to manage the card/avatar if the bare jid correspond to a MUC room
Goffi <goffi@goffi.org>
parents: 1683
diff changeset
95 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
96 avatar_hash = client._xep_0054_avatar_hashes[client.jid.userhost()]
2462
2cad04f38bac plugin XEP-0054: return always False in isRoom is plugin XEP-0045 is not available + raise NotFound if avatar is requested for a MUC room (not the occupants, the room itself)
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
97 except KeyError:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
98 log.info(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
99 _("No avatar in cache for {profile}")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
100 .format(profile=client.profile))
1970
200cd707a46d plugin XEP-0045, quick_frontend + primitivus (chat): cleaning of XEP-0045 (first pass):
Goffi <goffi@goffi.org>
parents: 1934
diff changeset
101 return True
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
102 x_elt = domish.Element((NS_VCARD_UPDATE, "x"))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
103 x_elt.addElement("photo", content=avatar_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
104 presence_elt.addChild(x_elt)
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
105 return True
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
106
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
107 async def profileConnecting(self, client):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
108 client._xep_0054_avatar_hashes = persistent.PersistentDict(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
109 NS_VCARD, client.profile)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
110 await client._xep_0054_avatar_hashes.load()
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
111
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
112 def savePhoto(self, client, photo_elt, entity_jid):
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
113 """Parse a <PHOTO> photo_elt and save the picture"""
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
114 # XXX: this method is launched in a separate thread
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
115 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
116 mime_type = str(next(photo_elt.elements(NS_VCARD, "TYPE")))
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
117 except StopIteration:
3003
e624550d5c24 plugin XEP-0054: reject image without MIME type if it's not PNG
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
118 mime_type = None
1317
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
119 else:
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
120 if not mime_type:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
121 # MIME type not known, we'll try autodetection below
3003
e624550d5c24 plugin XEP-0054: reject image without MIME type if it's not PNG
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
122 mime_type = None
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
123 elif mime_type == "image/x-png":
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
124 # XXX: this old MIME type is still used by some clients
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
125 mime_type = "image/png"
1317
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
126
2069
528e5fafc11b plugin XEP-0054(XEP-0153): ignore image formats other than gif, jpeg and png, and empty BINVAL
Goffi <goffi@goffi.org>
parents: 2064
diff changeset
127 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
128 buf = str(next(photo_elt.elements(NS_VCARD, "BINVAL")))
2069
528e5fafc11b plugin XEP-0054(XEP-0153): ignore image formats other than gif, jpeg and png, and empty BINVAL
Goffi <goffi@goffi.org>
parents: 2064
diff changeset
129 except StopIteration:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
130 log.warning("BINVAL element not found")
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
131 raise Failure(exceptions.NotFound())
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
132
2069
528e5fafc11b plugin XEP-0054(XEP-0153): ignore image formats other than gif, jpeg and png, and empty BINVAL
Goffi <goffi@goffi.org>
parents: 2064
diff changeset
133 if not buf:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
134 log.warning("empty avatar for {jid}".format(jid=entity_jid.full()))
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
135 raise Failure(exceptions.NotFound())
3003
e624550d5c24 plugin XEP-0054: reject image without MIME type if it's not PNG
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
136
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
137 log.debug(_("Decoding binary"))
2069
528e5fafc11b plugin XEP-0054(XEP-0153): ignore image formats other than gif, jpeg and png, and empty BINVAL
Goffi <goffi@goffi.org>
parents: 2064
diff changeset
138 decoded = b64decode(buf)
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
139 del buf
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
140
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
141 if mime_type is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
142 log.debug(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
143 f"no media type found specified for {entity_jid}'s avatar, trying to "
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
144 f"guess")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
145
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
146 try:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
147 mime_type = image.guess_type(io.BytesIO(decoded))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
148 except IOError as e:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
149 log.warning(f"Can't open avatar buffer: {e}")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
150
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
151 if mime_type is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
152 msg = f"Can't find media type for {entity_jid}'s avatar"
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
153 log.warning(msg)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
154 raise Failure(exceptions.DataError(msg))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
155
2069
528e5fafc11b plugin XEP-0054(XEP-0153): ignore image formats other than gif, jpeg and png, and empty BINVAL
Goffi <goffi@goffi.org>
parents: 2064
diff changeset
156 image_hash = sha1(decoded).hexdigest()
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
157 with self.host.common_cache.cacheData(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
158 PLUGIN_INFO["import_name"],
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
159 image_hash,
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
160 mime_type,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
161 ) as f:
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
162 f.write(decoded)
2069
528e5fafc11b plugin XEP-0054(XEP-0153): ignore image formats other than gif, jpeg and png, and empty BINVAL
Goffi <goffi@goffi.org>
parents: 2064
diff changeset
163 return image_hash
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
164
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
165 async def vCard2Dict(self, client, vcard_elt, entity_jid):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
166 """Convert a VCard_elt to a dict, and save binaries"""
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
167 log.debug(("parsing vcard_elt"))
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
168 vcard_dict = {}
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
169
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
170 for elem in vcard_elt.elements():
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
171 if elem.name == "FN":
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
172 vcard_dict["fullname"] = str(elem)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
173 elif elem.name == "NICKNAME":
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
174 nickname = vcard_dict["nickname"] = str(elem)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
175 await self._i.update(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
176 client,
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
177 IMPORT_NAME,
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
178 "nicknames",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
179 [nickname],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
180 entity_jid
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
181 )
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
182 elif elem.name == "URL":
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
183 vcard_dict["website"] = str(elem)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
184 elif elem.name == "EMAIL":
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
185 vcard_dict["email"] = str(elem)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
186 elif elem.name == "BDAY":
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
187 vcard_dict["birthday"] = str(elem)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
188 elif elem.name == "PHOTO":
2069
528e5fafc11b plugin XEP-0054(XEP-0153): ignore image formats other than gif, jpeg and png, and empty BINVAL
Goffi <goffi@goffi.org>
parents: 2064
diff changeset
189 # TODO: handle EXTVAL
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
190 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
191 avatar_hash = await threads.deferToThread(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
192 self.savePhoto, client, elem, entity_jid
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
193 )
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
194 except (exceptions.DataError, exceptions.NotFound):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
195 avatar_hash = ""
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
196 vcard_dict["avatar"] = avatar_hash
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
197 except Exception as e:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
198 log.error(f"avatar saving error: {e}")
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
199 avatar_hash = None
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
200 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
201 vcard_dict["avatar"] = avatar_hash
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
202 if avatar_hash is not None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
203 await client._xep_0054_avatar_hashes.aset(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
204 entity_jid.full(), avatar_hash)
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
205
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
206 if avatar_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
207 avatar_cache = self.host.common_cache.getMetadata(avatar_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
208 await self._i.update(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
209 client,
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
210 IMPORT_NAME,
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
211 "avatar",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
212 {
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
213 'path': avatar_cache['path'],
3326
9e1ba1e1179f plugin identity: added "filename" metadata for avatar
Goffi <goffi@goffi.org>
parents: 3279
diff changeset
214 'filename': avatar_cache['filename'],
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
215 'media_type': avatar_cache['mime_type'],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
216 'cache_uid': avatar_hash
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
217 },
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
218 entity_jid
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
219 )
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
220 else:
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
221 await self._i.update(
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
222 client, IMPORT_NAME, "avatar", None, entity_jid)
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
223 else:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
224 log.debug("FIXME: [{}] VCard_elt tag is not managed yet".format(elem.name))
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
225
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
226 return vcard_dict
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
227
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
228 async def getVCardElement(self, client, entity_jid):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
229 """Retrieve domish.Element of a VCard
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
230
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
231 @param entity_jid(jid.JID): entity from who we need the vCard
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
232 @raise DataError: we got an invalid answer
43
8a438a6ff587 Wix: added avatar in profile
Goffi <goffi@goffi.org>
parents: 42
diff changeset
233 """
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
234 iq_elt = client.IQ("get")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
235 iq_elt["from"] = client.jid.full()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
236 iq_elt["to"] = entity_jid.full()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
237 iq_elt.addElement("vCard", NS_VCARD)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
238 iq_ret_elt = await iq_elt.send(entity_jid.full())
2072
11fb5f5e2f89 plugin XEP-0054(XEP-0153): added a getAvatar:
Goffi <goffi@goffi.org>
parents: 2069
diff changeset
239 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
240 return next(iq_ret_elt.elements(NS_VCARD, "vCard"))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
241 except StopIteration:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
242 log.warning(_(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
243 "vCard element not found for {entity_jid}: {xml}"
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
244 ).format(entity_jid=entity_jid, xml=iq_ret_elt.toXml()))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
245 raise exceptions.DataError(f"no vCard element found for {entity_jid}")
2072
11fb5f5e2f89 plugin XEP-0054(XEP-0153): added a getAvatar:
Goffi <goffi@goffi.org>
parents: 2069
diff changeset
246
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
247 async def updateVCardElt(self, client, entity_jid, to_replace):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
248 """Create a vcard element to replace some metadata
2072
11fb5f5e2f89 plugin XEP-0054(XEP-0153): added a getAvatar:
Goffi <goffi@goffi.org>
parents: 2069
diff changeset
249
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
250 @param to_replace(list[str]): list of vcard element names to remove
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
251 """
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
252 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
253 # we first check if a vcard already exists, to keep data
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
254 vcard_elt = await self.getVCardElement(client, entity_jid)
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
255 except error.StanzaError as e:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
256 if e.condition == "item-not-found":
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
257 vcard_elt = domish.Element((NS_VCARD, "vCard"))
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
258 else:
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
259 raise e
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
260 except exceptions.DataError:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
261 vcard_elt = domish.Element((NS_VCARD, "vCard"))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
262 else:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
263 # the vcard exists, we need to remove elements that we'll replace
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
264 for elt_name in to_replace:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
265 try:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
266 elt = next(vcard_elt.elements(NS_VCARD, elt_name))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
267 except StopIteration:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
268 pass
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
269 else:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
270 vcard_elt.children.remove(elt)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
271
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
272 return vcard_elt
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
273
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
274 async def getCard(self, client, entity_jid):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
275 """Ask server for VCard
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
276
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
277 @param entity_jid(jid.JID): jid from which we want the VCard
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
278 @result(dict): vCard data
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
279 """
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
280 entity_jid = self._i.getIdentityJid(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
281 log.debug(f"Asking for {entity_jid}'s VCard")
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
282 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
283 vcard_elt = await self.getVCardElement(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
284 except exceptions.DataError:
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
285 self._i.update(client, IMPORT_NAME, "avatar", IMPORT_NAME, None, entity_jid)
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
286 except Exception as e:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
287 log.warning(_(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
288 "Can't get vCard for {entity_jid}: {e}"
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
289 ).format(entity_jid=entity_jid, e=e))
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
290 else:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
291 log.debug(_("VCard found"))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
292 return await self.vCard2Dict(client, vcard_elt, entity_jid)
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
293
3279
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
294 async def getAvatar(
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
295 self,
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
296 client: SatXMPPEntity,
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
297 entity_jid: jid.JID
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
298 ) -> Optional[dict]:
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
299 """Get avatar data
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
300
3279
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
301 @param entity: entity to get avatar from
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
302 @return: avatar metadata, or None if no avatar has been found
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
303 """
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
304 entity_jid = self._i.getIdentityJid(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
305 hashes_cache = client._xep_0054_avatar_hashes
3279
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
306 vcard = await self.getCard(client, entity_jid)
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
307 if vcard is None:
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
308 return None
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
309 try:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
310 avatar_hash = hashes_cache[entity_jid.full()]
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
311 except KeyError:
3279
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
312 if 'avatar' in vcard:
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
313 raise exceptions.InternalError(
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
314 "No avatar hash while avatar is found in vcard")
8de63fe6b5c9 plugin XEP-0054: don't use cache anymore in `getAvatar`:
Goffi <goffi@goffi.org>
parents: 3277
diff changeset
315 return None
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
316
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
317 if not avatar_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
318 return None
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
319
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
320 avatar_cache = self.host.common_cache.getMetadata(avatar_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
321 return self._i.avatarBuildMetadata(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
322 avatar_cache['path'], avatar_cache['mime_type'], avatar_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
323
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
324 def _buildSetAvatar(self, client, vcard_elt, avatar_data):
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
325 # XXX: this method is executed in a separate thread
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
326 if avatar_data["media_type"] == "image/svg+xml":
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
327 # for vector image, we save directly
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
328 img_buf = open(avatar_data["path"], "rb")
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
329 else:
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
330 # for bitmap image, we check size and resize if necessary
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
331 try:
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
332 img = Image.open(avatar_data["path"])
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
333 except IOError as e:
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
334 raise exceptions.DataError(f"Can't open image: {e}")
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
335
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
336 if img.size != AVATAR_DIM:
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
337 img.thumbnail(AVATAR_DIM)
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
338 if img.size[0] != img.size[1]: # we need to crop first
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
339 left, upper = (0, 0)
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
340 right, lower = img.size
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
341 offset = abs(right - lower) / 2
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
342 if right == min(img.size):
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
343 upper += offset
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
344 lower -= offset
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
345 else:
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
346 left += offset
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
347 right -= offset
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
348 img = img.crop((left, upper, right, lower))
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
349 img_buf = io.BytesIO()
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
350 # PNG is well supported among clients, so we convert to this format
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
351 img.save(img_buf, "PNG")
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
352 img_buf.seek(0)
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
353 avatar_data["media_type"] = "image/png"
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
354
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
355 media_type = avatar_data["media_type"]
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
356 photo_elt = vcard_elt.addElement("PHOTO")
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
357 photo_elt.addElement("TYPE", content=media_type)
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
358 image_b64 = b64encode(img_buf.read()).decode()
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
359 img_buf.seek(0)
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
360 photo_elt.addElement("BINVAL", content=image_b64)
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
361 image_hash = sha1(img_buf.read()).hexdigest()
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
362 img_buf.seek(0)
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
363 with self.host.common_cache.cacheData(
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
364 PLUGIN_INFO["import_name"], image_hash, media_type
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
365 ) as f:
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
366 f.write(img_buf.read())
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
367 avatar_data['path'] = Path(f.name)
3326
9e1ba1e1179f plugin identity: added "filename" metadata for avatar
Goffi <goffi@goffi.org>
parents: 3279
diff changeset
368 avatar_data['filename'] = avatar_data['path'].name
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
369 avatar_data['cache_uid'] = image_hash
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
370 return image_hash
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
371
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
372 async def setAvatar(self, client, avatar_data, entity):
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
373 """Set avatar of the profile
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
374
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
375 @param avatar_data(dict): data of the image to use as avatar, as built by
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
376 IDENTITY plugin.
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
377 @param entity(jid.JID): entity whose avatar must be changed
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
378 """
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
379 vcard_elt = await self.updateVCardElt(client, entity, ['PHOTO'])
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
380
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
381 iq_elt = client.IQ()
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
382 iq_elt.addChild(vcard_elt)
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
383 await threads.deferToThread(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
384 self._buildSetAvatar, client, vcard_elt, avatar_data
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
385 )
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
386 # image is now at the right size/format
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
387
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
388 await iq_elt.send()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
389
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
390 # FIXME: should send the current presence, not always "available" !
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
391 await client.presence.available()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
392
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
393 async def getNicknames(self, client, entity):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
394 """get nick from cache, or check vCard
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
395
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
396 @param entity(jid.JID): entity to get nick from
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
397 @return(list[str]): nicknames found
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
398 """
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
399 vcard_data = await self.getCard(client, entity)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
400 try:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
401 return [vcard_data['nickname']]
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
402 except (KeyError, TypeError):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
403 return []
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
404
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
405 async def setNicknames(self, client, nicknames, entity):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
406 """Update our vCard and set a nickname
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
407
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
408 @param nicknames(list[str]): new nicknames to use
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
409 only first item of this list will be used here
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
410 """
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
411 nick = nicknames[0].strip()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
412
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
413 vcard_elt = await self.updateVCardElt(client, entity, ['NICKNAME'])
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
414
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
415 if nick:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
416 vcard_elt.addElement((NS_VCARD, "NICKNAME"), content=nick)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
417 iq_elt = client.IQ()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
418 iq_elt.addChild(vcard_elt)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
419 await iq_elt.send()
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
420
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
421
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
422 @implementer(iwokkel.IDisco)
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
423 class XEP_0054_handler(XMPPHandler):
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
424
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
425 def __init__(self, plugin_parent):
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
426 self.plugin_parent = plugin_parent
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
427 self.host = plugin_parent.host
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
428
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
429 def connectionInitialized(self):
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
430 self.xmlstream.addObserver(VCARD_UPDATE, self._update)
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
431
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
432 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
433 return [disco.DiscoFeature(NS_VCARD)]
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
434
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
435 def getDiscoItems(self, requestor, target, nodeIdentifier=""):
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
436 return []
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
437
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
438 def _checkAvatarHash(self, client, entity, given_hash):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
439 """Check that hash in cache (i.e. computed hash) is the same as given one"""
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
440 # XXX: if they differ, the avatar will be requested on each connection
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
441 # TODO: try to avoid re-requesting avatar in this case
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
442 computed_hash = client._xep_0054_avatar_hashes[entity.full]
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
443 if computed_hash != given_hash:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
444 log.warning(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
445 "computed hash differs from given hash for {entity}:\n"
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
446 "computed: {computed}\ngiven: {given}".format(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
447 entity=entity, computed=computed_hash, given=given_hash
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
448 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
449 )
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
450
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
451 async def update(self, presence):
1317
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
452 """Called on <presence/> stanza with vcard data
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
453
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
454 Check for avatar information, and get VCard if needed
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
455 @param presence(domish.Element): <presence/> stanza
48
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
456 """
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
457 client = self.parent
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
458 entity_jid = self.plugin_parent._i.getIdentityJid(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
459 client, jid.JID(presence["from"]))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
460
1682
61391d863709 plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
461 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
462 x_elt = next(presence.elements(NS_VCARD_UPDATE, "x"))
1682
61391d863709 plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
463 except StopIteration:
61391d863709 plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
464 return
61391d863709 plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
465
61391d863709 plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
466 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
467 photo_elt = next(x_elt.elements(NS_VCARD_UPDATE, "photo"))
1682
61391d863709 plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
468 except StopIteration:
61391d863709 plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
469 return
1317
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
470
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
471 new_hash = str(photo_elt).strip()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
472 if new_hash == HASH_SHA1_EMPTY:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
473 new_hash = ""
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
474
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
475 hashes_cache = client._xep_0054_avatar_hashes
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
476
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
477 old_hash = hashes_cache.get(entity_jid.full())
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
478
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
479 if old_hash == new_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
480 # no change, we can return…
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
481 if new_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
482 # …but we double check that avatar is in cache
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
483 avatar_cache = self.host.common_cache.getMetadata(new_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
484 if avatar_cache is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
485 log.debug(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
486 f"Avatar for [{entity_jid}] is known but not in cache, we get "
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
487 f"it"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
488 )
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
489 # getCard will put the avatar in cache
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
490 await self.plugin_parent.getCard(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
491 else:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
492 log.debug(f"avatar for {entity_jid} is already in cache")
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
493 return
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
494
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
495 if new_hash is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
496 # XXX: we use empty string to indicate that there is no avatar
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
497 new_hash = ""
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
498
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
499 await hashes_cache.aset(entity_jid.full(), new_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
500
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
501 if not new_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
502 await self.plugin_parent._i.update(
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
503 client, IMPORT_NAME, "avatar", None, entity_jid)
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
504 # the avatar has been removed, no need to go further
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
505 return
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
506
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
507 avatar_cache = self.host.common_cache.getMetadata(new_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
508 if avatar_cache is not None:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
509 log.debug(
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
510 f"New avatar found for [{entity_jid}], it's already in cache, we use it"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
511 )
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
512 await self.plugin_parent._i.update(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
513 client,
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
514 IMPORT_NAME, "avatar",
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
515 {
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
516 'path': avatar_cache['path'],
3326
9e1ba1e1179f plugin identity: added "filename" metadata for avatar
Goffi <goffi@goffi.org>
parents: 3279
diff changeset
517 'filename': avatar_cache['filename'],
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
518 'media_type': avatar_cache['mime_type'],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
519 'cache_uid': new_hash,
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
520 },
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
521 entity_jid
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
522 )
1682
61391d863709 plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
523 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
524 log.debug(
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
525 "New avatar found for [{entity_jid}], requesting vcard"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
526 )
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
527 vcard = await self.plugin_parent.getCard(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
528 if vcard is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
529 log.warning(f"Unexpected empty vCard for {entity_jid}")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
530 return
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
531 await self._checkAvatarHash(client, entity_jid, new_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
532
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
533 def _update(self, presence):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
534 defer.ensureDeferred(self.update(presence))