annotate sat/plugins/plugin_xep_0054.py @ 3456:6deea0d8d0e7

plugin tickets, merge_requests: renamed "tickets" feature to "lists": this feature is more generic than only "tickets" for technical stuff, thus the name "lists" seems more appropriate.
author Goffi <goffi@goffi.org>
date Thu, 04 Feb 2021 21:05:21 +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))