annotate sat/plugins/plugin_xep_0054.py @ 3277:cf07641b764d

plugin identity: fixed infinite loop on nicknames update
author Goffi <goffi@goffi.org>
date Mon, 18 May 2020 23:52:34 +0200
parents 7aa01e262e05
children 8de63fe6b5c9
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
3185
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
24 from zope.interface import implementer
939
01342bfe9f41 wix: fixed onShowProfile
Goffi <goffi@goffi.org>
parents: 916
diff changeset
25 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
26 from twisted.words.protocols.jabber import jid, error
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
27 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
28 from twisted.python.failure import Failure
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from wokkel import disco, iwokkel
3185
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
30 from sat.core import exceptions
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
31 from sat.core.i18n import _
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
32 from sat.core.constants import Const as C
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
33 from sat.core.log import getLogger
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
34 from sat.memory import persistent
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
35 from sat.tools import image
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
36
3185
554b3b632378 memory (cache): purge + pathlib:
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
37 log = getLogger(__name__)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
38
1542
94901070478e plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents: 1437
diff changeset
39 try:
94901070478e plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents: 1437
diff changeset
40 from PIL import Image
94901070478e plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents: 1437
diff changeset
41 except:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
42 raise exceptions.MissingModule(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
43 "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
44 )
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
45
48
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
46 try:
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
47 from twisted.words.protocols.xmlstream import XMPPHandler
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
48 except ImportError:
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
49 from wokkel.subprotocols import XMPPHandler
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
50
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
51 IMPORT_NAME = "XEP-0054"
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
52
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
53 PLUGIN_INFO = {
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
54 C.PI_NAME: "XEP 0054 Plugin",
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
55 C.PI_IMPORT_NAME: IMPORT_NAME,
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
56 C.PI_TYPE: "XEP",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
57 C.PI_PROTOCOLS: ["XEP-0054", "XEP-0153"],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
58 C.PI_DEPENDENCIES: ["IDENTITY"],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
59 C.PI_RECOMMENDATIONS: [],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
60 C.PI_MAIN: "XEP_0054",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
61 C.PI_HANDLER: "yes",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
62 C.PI_DESCRIPTION: _("""Implementation of vcard-temp"""),
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
63 }
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
64
365
efbfccfed623 core: local_dir moved to config file
Goffi <goffi@goffi.org>
parents: 291
diff changeset
65 AVATAR_PATH = "avatars"
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
66 AVATAR_DIM = (128, 128)
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
67
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
68 IQ_GET = '/iq[@type="get"]'
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
69 NS_VCARD = "vcard-temp"
594
e629371a28d3 Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 588
diff changeset
70 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
71
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
72 PRESENCE = "/presence"
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
73 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
74 VCARD_UPDATE = PRESENCE + '/x[@xmlns="' + NS_VCARD_UPDATE + '"]'
48
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
75
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
76 HASH_SHA1_EMPTY = "da39a3ee5e6b4b0d3255bfef95601890afd80709"
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
77
594
e629371a28d3 Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 588
diff changeset
78
588
beaf6bec2fcd Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 587
diff changeset
79 class XEP_0054(object):
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
80
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
81 def __init__(self, host):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
82 log.info(_("Plugin XEP_0054 initialization"))
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
83 self.host = host
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
84 self._i = host.plugins['IDENTITY']
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
85 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
86 self._i.register(IMPORT_NAME, 'nicknames', self.getNicknames, self.setNicknames)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
87 host.trigger.add("presence_available", self.presenceAvailableTrigger)
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
88
2144
1d3f73e065e1 core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents: 2123
diff changeset
89 def getHandler(self, client):
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
90 return XEP_0054_handler(self)
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
91
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
92 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
93 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
94 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
95 except KeyError:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
96 log.info(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
97 _("No avatar in cache for {profile}")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
98 .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
99 return True
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
100 x_elt = domish.Element((NS_VCARD_UPDATE, "x"))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
101 x_elt.addElement("photo", content=avatar_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
102 presence_elt.addChild(x_elt)
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
103 return True
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
104
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
105 async def profileConnecting(self, client):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
106 client._xep_0054_avatar_hashes = persistent.PersistentDict(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
107 NS_VCARD, client.profile)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
108 await client._xep_0054_avatar_hashes.load()
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
109
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
110 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
111 """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
112 # 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
113 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
114 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
115 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
116 mime_type = None
1317
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
117 else:
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
118 if not mime_type:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
119 # 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
120 mime_type = None
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
121 elif mime_type == "image/x-png":
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
122 # XXX: this old MIME type is still used by some clients
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
123 mime_type = "image/png"
1317
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
124
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
125 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
126 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
127 except StopIteration:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
128 log.warning("BINVAL element not found")
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
129 raise Failure(exceptions.NotFound())
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
130
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
131 if not buf:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
132 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
133 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
134
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
135 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
136 decoded = b64decode(buf)
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
137 del buf
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
138
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
139 if mime_type is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
140 log.debug(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
141 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
142 f"guess")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
143
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
144 try:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
145 mime_type = image.guess_type(io.BytesIO(decoded))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
146 except IOError as e:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
147 log.warning(f"Can't open avatar buffer: {e}")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
148
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
149 if mime_type is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
150 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
151 log.warning(msg)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
152 raise Failure(exceptions.DataError(msg))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
153
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
154 image_hash = sha1(decoded).hexdigest()
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
155 with self.host.common_cache.cacheData(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
156 PLUGIN_INFO["import_name"],
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
157 image_hash,
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
158 mime_type,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
159 ) as f:
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
160 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
161 return image_hash
42
874de3020e1c Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff changeset
162
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
163 async def vCard2Dict(self, client, vcard_elt, entity_jid):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
164 """Convert a VCard_elt to a dict, and save binaries"""
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
165 log.debug(("parsing vcard_elt"))
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
166 vcard_dict = {}
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
167
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
168 for elem in vcard_elt.elements():
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
169 if elem.name == "FN":
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
170 vcard_dict["fullname"] = str(elem)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
171 elif elem.name == "NICKNAME":
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
172 nickname = vcard_dict["nickname"] = str(elem)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
173 await self._i.update(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
174 client,
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
175 IMPORT_NAME,
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
176 "nicknames",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
177 [nickname],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
178 entity_jid
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
179 )
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
180 elif elem.name == "URL":
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
181 vcard_dict["website"] = str(elem)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
182 elif elem.name == "EMAIL":
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
183 vcard_dict["email"] = str(elem)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
184 elif elem.name == "BDAY":
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
185 vcard_dict["birthday"] = str(elem)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
186 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
187 # TODO: handle EXTVAL
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
188 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
189 avatar_hash = await threads.deferToThread(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
190 self.savePhoto, client, elem, entity_jid
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
191 )
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
192 except (exceptions.DataError, exceptions.NotFound):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
193 avatar_hash = ""
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
194 vcard_dict["avatar"] = avatar_hash
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
195 except Exception as e:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
196 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
197 avatar_hash = None
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
198 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
199 vcard_dict["avatar"] = avatar_hash
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
200 if avatar_hash is not None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
201 await client._xep_0054_avatar_hashes.aset(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
202 entity_jid.full(), avatar_hash)
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
203
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
204 if avatar_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
205 avatar_cache = self.host.common_cache.getMetadata(avatar_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
206 await self._i.update(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
207 client,
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
208 IMPORT_NAME,
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
209 "avatar",
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
210 {
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
211 'path': avatar_cache['path'],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
212 'media_type': avatar_cache['mime_type'],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
213 'cache_uid': avatar_hash
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
214 },
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
215 entity_jid
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
216 )
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
217 else:
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
218 await self._i.update(
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
219 client, IMPORT_NAME, "avatar", None, entity_jid)
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
220 else:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
221 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
222
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
223 return vcard_dict
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
224
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
225 async def getVCardElement(self, client, entity_jid):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
226 """Retrieve domish.Element of a VCard
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 @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
229 @raise DataError: we got an invalid answer
43
8a438a6ff587 Wix: added avatar in profile
Goffi <goffi@goffi.org>
parents: 42
diff changeset
230 """
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
231 iq_elt = client.IQ("get")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
232 iq_elt["from"] = client.jid.full()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
233 iq_elt["to"] = entity_jid.full()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
234 iq_elt.addElement("vCard", NS_VCARD)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
235 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
236 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
237 return next(iq_ret_elt.elements(NS_VCARD, "vCard"))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
238 except StopIteration:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
239 log.warning(_(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
240 "vCard element not found for {entity_jid}: {xml}"
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
241 ).format(entity_jid=entity_jid, xml=iq_ret_elt.toXml()))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
242 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
243
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
244 async def updateVCardElt(self, client, entity_jid, to_replace):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
245 """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
246
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
247 @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
248 """
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
249 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
250 # we first check if a vcard already exists, to keep data
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
251 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
252 except error.StanzaError as e:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
253 if e.condition == "item-not-found":
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
254 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
255 else:
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
256 raise e
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
257 except exceptions.DataError:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
258 vcard_elt = domish.Element((NS_VCARD, "vCard"))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
259 else:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
260 # 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
261 for elt_name in to_replace:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
262 try:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
263 elt = next(vcard_elt.elements(NS_VCARD, elt_name))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
264 except StopIteration:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
265 pass
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
266 else:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
267 vcard_elt.children.remove(elt)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
268
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
269 return vcard_elt
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
270
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
271 async def getCard(self, client, entity_jid):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
272 """Ask server for VCard
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 @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
275 @result(dict): vCard data
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 entity_jid = self._i.getIdentityJid(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
278 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
279 try:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
280 vcard_elt = await self.getVCardElement(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
281 except exceptions.DataError:
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
282 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
283 except Exception as e:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
284 log.warning(_(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
285 "Can't get vCard for {entity_jid}: {e}"
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
286 ).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
287 else:
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
288 log.debug(_("VCard found"))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
289 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
290
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
291 async def getAvatar(self, client, entity_jid):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
292 """Get avatar full path or hash
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
293
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
294 if avatar is not in local cache, it will be requested to the server
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
295 @param entity(jid.JID): entity to get avatar from
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
296
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
297 """
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
298 entity_jid = self._i.getIdentityJid(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
299 hashes_cache = client._xep_0054_avatar_hashes
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
300 try:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
301 avatar_hash = hashes_cache[entity_jid.full()]
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
302 except KeyError:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
303 log.debug(f"avatar for {entity_jid} is not in cache, we retrieve it")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
304 vcard = await self.getCard(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
305 if vcard is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
306 return None
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
307 try:
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
308 avatar_hash = hashes_cache[entity_jid.full()]
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
309 except KeyError:
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
310 if 'avatar' in vcard:
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
311 raise exceptions.InternalError(
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
312 "No avatar hash while avatar is found in vcard")
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
313 return None
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
314
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
315 if not avatar_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
316 return None
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
317
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
318 avatar_cache = self.host.common_cache.getMetadata(avatar_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
319 if avatar_cache is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
320 log.debug("avatar is no more in cache, we re-download it")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
321 vcard = await self.getCard(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
322 if vcard is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
323 return None
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
324 avatar_cache = self.host.common_cache.getMetadata(avatar_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
325
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
326 return self._i.avatarBuildMetadata(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
327 avatar_cache['path'], avatar_cache['mime_type'], avatar_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
328
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
329 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
330 # 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
331 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
332 # 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
333 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
334 else:
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
335 # 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
336 try:
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
337 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
338 except IOError as e:
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
339 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
340
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
341 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
342 img.thumbnail(AVATAR_DIM)
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
343 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
344 left, upper = (0, 0)
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
345 right, lower = img.size
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
346 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
347 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
348 upper += offset
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
349 lower -= offset
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
350 else:
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
351 left += offset
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
352 right -= offset
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
353 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
354 img_buf = io.BytesIO()
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
355 # 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
356 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
357 img_buf.seek(0)
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
358 avatar_data["media_type"] = "image/png"
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
359
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
360 media_type = avatar_data["media_type"]
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
361 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
362 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
363 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
364 img_buf.seek(0)
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
365 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
366 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
367 img_buf.seek(0)
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
368 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
369 PLUGIN_INFO["import_name"], image_hash, media_type
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
370 ) as f:
3258
7aa01e262e05 plugin XEP-0054: SVG images can now be uploaded for avatars.
Goffi <goffi@goffi.org>
parents: 3254
diff changeset
371 f.write(img_buf.read())
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
372 avatar_data['path'] = Path(f.name)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
373 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
374 return image_hash
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
375
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
376 async def setAvatar(self, client, avatar_data, entity):
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
377 """Set avatar of the profile
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 @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
380 IDENTITY plugin.
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
381 @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
382 """
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
383 vcard_elt = await self.updateVCardElt(client, entity, ['PHOTO'])
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
384
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
385 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
386 iq_elt.addChild(vcard_elt)
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
387 await threads.deferToThread(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
388 self._buildSetAvatar, client, vcard_elt, avatar_data
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
389 )
2252
cffa50c9f26b plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents: 2145
diff changeset
390 # image is now at the right size/format
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
391
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
392 await iq_elt.send()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
393
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
394 # FIXME: should send the current presence, not always "available" !
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
395 await client.presence.available()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
396
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
397 async def getNicknames(self, client, entity):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
398 """get nick from cache, or check vCard
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
399
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
400 @param entity(jid.JID): entity to get nick from
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
401 @return(list[str]): nicknames found
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
402 """
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
403 vcard_data = await self.getCard(client, entity)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
404 try:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
405 return [vcard_data['nickname']]
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
406 except (KeyError, TypeError):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
407 return []
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
408
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
409 async def setNicknames(self, client, nicknames, entity):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
410 """Update our vCard and set a nickname
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
411
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
412 @param nicknames(list[str]): new nicknames to use
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
413 only first item of this list will be used here
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 nick = nicknames[0].strip()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
416
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
417 vcard_elt = await self.updateVCardElt(client, entity, ['NICKNAME'])
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
418
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
419 if nick:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
420 vcard_elt.addElement((NS_VCARD, "NICKNAME"), content=nick)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
421 iq_elt = client.IQ()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
422 iq_elt.addChild(vcard_elt)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
423 await iq_elt.send()
562
0bb2e0d1c878 core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents: 560
diff changeset
424
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
425
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
426 @implementer(iwokkel.IDisco)
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
427 class XEP_0054_handler(XMPPHandler):
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
428
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
429 def __init__(self, plugin_parent):
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
430 self.plugin_parent = plugin_parent
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
431 self.host = plugin_parent.host
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
432
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
433 def connectionInitialized(self):
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
434 self.xmlstream.addObserver(VCARD_UPDATE, self._update)
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
435
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
436 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
437 return [disco.DiscoFeature(NS_VCARD)]
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
438
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
439 def getDiscoItems(self, requestor, target, nodeIdentifier=""):
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 57
diff changeset
440 return []
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
441
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
442 def _checkAvatarHash(self, client, entity, given_hash):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
443 """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
444 # 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
445 # TODO: try to avoid re-requesting avatar in this case
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
446 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
447 if computed_hash != given_hash:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
448 log.warning(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
449 "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
450 "computed: {computed}\ngiven: {given}".format(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
451 entity=entity, computed=computed_hash, given=given_hash
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
452 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
453 )
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
454
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
455 async def update(self, presence):
1317
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
456 """Called on <presence/> stanza with vcard data
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
457
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
458 Check for avatar information, and get VCard if needed
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
459 @param presence(domish.Element): <presence/> stanza
48
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 44
diff changeset
460 """
2123
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
461 client = self.parent
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
462 entity_jid = self.plugin_parent._i.getIdentityJid(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
463 client, jid.JID(presence["from"]))
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
464
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
465 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
466 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
467 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
468 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
469
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
470 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 3003
diff changeset
471 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
472 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
473 return
1317
bd69d341d969 plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents: 1315
diff changeset
474
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
475 new_hash = str(photo_elt).strip()
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
476 if new_hash == HASH_SHA1_EMPTY:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
477 new_hash = ""
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
478
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
479 hashes_cache = client._xep_0054_avatar_hashes
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
480
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
481 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
482
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
483 if old_hash == new_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
484 # no change, we can return…
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
485 if new_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
486 # …but we double check that avatar is in cache
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
487 avatar_cache = self.host.common_cache.getMetadata(new_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
488 if avatar_cache is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
489 log.debug(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
490 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
491 f"it"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
492 )
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
493 # getCard will put the avatar in cache
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
494 await self.plugin_parent.getCard(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
495 else:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
496 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
497 return
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
498
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
499 if new_hash is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
500 # 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
501 new_hash = ""
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
502
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
503 await hashes_cache.aset(entity_jid.full(), new_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
504
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
505 if not new_hash:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
506 await self.plugin_parent._i.update(
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
507 client, IMPORT_NAME, "avatar", None, entity_jid)
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
508 # 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
509 return
c42aab22c2c0 plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
510
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
511 avatar_cache = self.host.common_cache.getMetadata(new_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
512 if avatar_cache is not None:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
513 log.debug(
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
514 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
515 )
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
516 await self.plugin_parent._i.update(
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
517 client,
3277
cf07641b764d plugin identity: fixed infinite loop on nicknames update
Goffi <goffi@goffi.org>
parents: 3258
diff changeset
518 IMPORT_NAME, "avatar",
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
519 {
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
520 'path': avatar_cache['path'],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
521 'media_type': avatar_cache['mime_type'],
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
522 'cache_uid': new_hash,
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
523 },
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
524 entity_jid
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
525 )
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
526 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
527 log.debug(
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
528 "New avatar found for [{entity_jid}], requesting vcard"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2581
diff changeset
529 )
3254
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
530 vcard = await self.plugin_parent.getCard(client, entity_jid)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
531 if vcard is None:
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
532 log.warning(f"Unexpected empty vCard for {entity_jid}")
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
533 return
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
534 await self._checkAvatarHash(client, entity_jid, new_hash)
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
535
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
536 def _update(self, presence):
6cf4bd6972c2 core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents: 3199
diff changeset
537 defer.ensureDeferred(self.update(presence))