Mercurial > libervia-backend
annotate sat/plugins/plugin_xep_0054.py @ 3254:6cf4bd6972c2
core, frontends: avatar refactoring:
/!\ huge commit
Avatar logic has been reworked around the IDENTITY plugin: plugins able to handle avatar
or other identity related metadata (like nicknames) register to IDENTITY plugin in the
same way as for other features like download/upload. Once registered, IDENTITY plugin will
call them when suitable in order of priority, and handle caching.
Methods to manage those metadata from frontend now use serialised data.
For now `avatar` and `nicknames` are handled:
- `avatar` is now a dict with `path` + metadata like `media_type`, instead of just a string
path
- `nicknames` is now a list of nicknames in order of priority. This list is never empty,
and `nicknames[0]` should be the preferred nickname to use by frontends in most cases.
In addition to contact specified nicknames, user set nickname (the one set in roster) is
used in priority when available.
Among the side changes done with this commit, there are:
- a new `contactGet` bridge method to get roster metadata for a single contact
- SatPresenceProtocol.send returns a Deferred to check when it has actually been sent
- memory's methods to handle entities data now use `client` as first argument
- metadata filter can be specified with `getIdentity`
- `getAvatar` and `setAvatar` are now part of the IDENTITY plugin instead of XEP-0054 (and
there signature has changed)
- `isRoom` and `getBareOrFull` are now part of XEP-0045 plugin
- jp avatar/get command uses `xdg-open` first when available for `--show` flag
- `--no-cache` has been added to jp avatar/get and identity/get
- jp identity/set has been simplified, explicit options (`--nickname` only for now) are
used instead of `--field`. `--field` may come back in the future if necessary for extra
data.
- QuickContactList `SetContact` now handle None as a value, and doesn't use it to delete the
metadata anymore
- improved cache handling for `metadata` and `nicknames` in quick frontend
- new `default` argument in QuickContactList `getCache`
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 14 Apr 2020 21:00:33 +0200 |
parents | 5afd7416ca2d |
children | 7aa01e262e05 |
rev | line source |
---|---|
3028 | 1 #!/usr/bin/env python3 |
3137 | 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 | 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 | 21 from base64 import b64decode, b64encode |
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 | 24 from zope.interface import implementer |
939 | 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 | 30 from sat.core import exceptions |
31 from sat.core.i18n import _ | |
32 from sat.core.constants import Const as C | |
33 from sat.core.log import getLogger | |
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 | 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 | 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 | 46 try: |
47 from twisted.words.protocols.xmlstream import XMPPHandler | |
48 except ImportError: | |
49 from wokkel.subprotocols import XMPPHandler | |
50 | |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
51 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
52 PLUGIN_INFO = { |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
53 C.PI_NAME: "XEP 0054 Plugin", |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
54 C.PI_IMPORT_NAME: "XEP-0054", |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
55 C.PI_TYPE: "XEP", |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
56 C.PI_PROTOCOLS: ["XEP-0054", "XEP-0153"], |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
57 C.PI_DEPENDENCIES: ["IDENTITY"], |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
58 C.PI_RECOMMENDATIONS: [], |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
59 C.PI_MAIN: "XEP_0054", |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
60 C.PI_HANDLER: "yes", |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
61 C.PI_DESCRIPTION: _("""Implementation of vcard-temp"""), |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
62 } |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
63 |
365
efbfccfed623
core: local_dir moved to config file
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
64 AVATAR_PATH = "avatars" |
3040 | 65 AVATAR_DIM = (128, 128) |
42
874de3020e1c
Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
66 |
874de3020e1c
Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
67 IQ_GET = '/iq[@type="get"]' |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
68 NS_VCARD = "vcard-temp" |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
69 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
|
70 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
71 PRESENCE = "/presence" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
72 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
|
73 VCARD_UPDATE = PRESENCE + '/x[@xmlns="' + NS_VCARD_UPDATE + '"]' |
48 | 74 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
75 HASH_SHA1_EMPTY = "da39a3ee5e6b4b0d3255bfef95601890afd80709" |
42
874de3020e1c
Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
76 |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
77 |
588
beaf6bec2fcd
Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
587
diff
changeset
|
78 class XEP_0054(object): |
42
874de3020e1c
Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
79 |
874de3020e1c
Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
80 def __init__(self, host): |
3028 | 81 log.info(_("Plugin XEP_0054 initialization")) |
42
874de3020e1c
Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
82 self.host = host |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
83 self._i = host.plugins['IDENTITY'] |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
84 self._i.register('avatar', self.getAvatar, self.setAvatar) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
85 self._i.register('nicknames', self.getNicknames, self.setNicknames) |
3028 | 86 host.trigger.add("presence_available", self.presenceAvailableTrigger) |
64 | 87 |
2144
1d3f73e065e1
core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents:
2123
diff
changeset
|
88 def getHandler(self, client): |
562
0bb2e0d1c878
core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents:
560
diff
changeset
|
89 return XEP_0054_handler(self) |
0bb2e0d1c878
core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents:
560
diff
changeset
|
90 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
91 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
|
92 try: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
93 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
|
94 except KeyError: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
95 log.info( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
96 _("No avatar in cache for {profile}") |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
97 .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
|
98 return True |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
99 x_elt = domish.Element((NS_VCARD_UPDATE, "x")) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
100 x_elt.addElement("photo", content=avatar_hash) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
101 presence_elt.addChild(x_elt) |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
102 return True |
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
103 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
104 async def profileConnecting(self, client): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
105 client._xep_0054_avatar_hashes = persistent.PersistentDict( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
106 NS_VCARD, client.profile) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
107 await client._xep_0054_avatar_hashes.load() |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
108 |
1970
200cd707a46d
plugin XEP-0045, quick_frontend + primitivus (chat): cleaning of XEP-0045 (first pass):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
109 def getCache(self, client, entity_jid, name): |
48 | 110 """return cached value for jid |
1293
0541cb64217e
plugin XEP-0054: couple of fixes in VCard/avatar management:
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
111 |
2252
cffa50c9f26b
plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents:
2145
diff
changeset
|
112 @param entity_jid(jid.JID): target contact |
cffa50c9f26b
plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents:
2145
diff
changeset
|
113 @param name(unicode): name of the value ('nick' or 'avatar') |
cffa50c9f26b
plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents:
2145
diff
changeset
|
114 @return(unicode, None): wanted value or None""" |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
115 entity_jid = self._i.getIdentityJid(client, entity_jid) |
48 | 116 try: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
117 data = self.host.memory.getEntityData(client, entity_jid, [name]) |
504
65ecbb473cbb
core, quick frontend, plugin xep-0054, bridge: use of memory's entities data for vcard:
Goffi <goffi@goffi.org>
parents:
485
diff
changeset
|
118 except exceptions.UnknownEntityError: |
48 | 119 return None |
504
65ecbb473cbb
core, quick frontend, plugin xep-0054, bridge: use of memory's entities data for vcard:
Goffi <goffi@goffi.org>
parents:
485
diff
changeset
|
120 return data.get(name) |
48 | 121 |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
122 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
|
123 """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
|
124 # 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
|
125 try: |
3028 | 126 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
|
127 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
|
128 mime_type = None |
1317
bd69d341d969
plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents:
1315
diff
changeset
|
129 else: |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
130 if not mime_type: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
131 # 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
|
132 mime_type = None |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
133 elif mime_type == "image/x-png": |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
134 # XXX: this old MIME type is still used by some clients |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
135 mime_type = "image/png" |
1317
bd69d341d969
plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents:
1315
diff
changeset
|
136 |
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
|
137 try: |
3028 | 138 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
|
139 except StopIteration: |
3028 | 140 log.warning("BINVAL element not found") |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
141 raise Failure(exceptions.NotFound()) |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
142 |
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
|
143 if not buf: |
3028 | 144 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
|
145 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
|
146 |
3028 | 147 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
|
148 decoded = b64decode(buf) |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
149 del buf |
3254
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 log.debug( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
153 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
|
154 f"guess") |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
155 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
156 try: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
157 mime_type = image.guess_type(io.BytesIO(decoded)) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
158 except IOError as e: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
159 log.warning(f"Can't open avatar buffer: {e}") |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
160 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
161 if mime_type is None: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
162 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
|
163 log.warning(msg) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
164 raise Failure(exceptions.DataError(msg)) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
165 |
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
|
166 image_hash = sha1(decoded).hexdigest() |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
167 with self.host.common_cache.cacheData( |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
168 PLUGIN_INFO["import_name"], |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
169 image_hash, |
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
170 mime_type, |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
171 ) as f: |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
172 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
|
173 return image_hash |
42
874de3020e1c
Initial VCard (XEP-0054) support + misc fixes
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
174 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
175 async def vCard2Dict(self, client, vcard_elt, entity_jid): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
176 """Convert a VCard_elt to a dict, and save binaries""" |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
177 log.debug(("parsing vcard_elt")) |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
178 vcard_dict = {} |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
179 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
180 for elem in vcard_elt.elements(): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
181 if elem.name == "FN": |
3028 | 182 vcard_dict["fullname"] = str(elem) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
183 elif elem.name == "NICKNAME": |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
184 nickname = vcard_dict["nickname"] = str(elem) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
185 await self._i.update( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
186 client, |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
187 "nicknames", |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
188 [nickname], |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
189 entity_jid |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
190 ) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
191 elif elem.name == "URL": |
3028 | 192 vcard_dict["website"] = str(elem) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
193 elif elem.name == "EMAIL": |
3028 | 194 vcard_dict["email"] = str(elem) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
195 elif elem.name == "BDAY": |
3028 | 196 vcard_dict["birthday"] = str(elem) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
197 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
|
198 # TODO: handle EXTVAL |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
199 try: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
200 avatar_hash = await threads.deferToThread( |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
201 self.savePhoto, client, elem, entity_jid |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
202 ) |
3040 | 203 except (exceptions.DataError, exceptions.NotFound): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
204 avatar_hash = "" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
205 vcard_dict["avatar"] = avatar_hash |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
206 except Exception as e: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
207 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
|
208 avatar_hash = None |
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
209 else: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
210 vcard_dict["avatar"] = avatar_hash |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
211 if avatar_hash is not None: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
212 await client._xep_0054_avatar_hashes.aset( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
213 entity_jid.full(), avatar_hash) |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
214 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
215 if avatar_hash: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
216 avatar_cache = self.host.common_cache.getMetadata(avatar_hash) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
217 await self._i.update( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
218 client, |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
219 "avatar", |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
220 { |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
221 'path': avatar_cache['path'], |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
222 'media_type': avatar_cache['mime_type'], |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
223 'cache_uid': avatar_hash |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
224 }, |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
225 entity_jid |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
226 ) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
227 else: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
228 await self._i.update(client, "avatar", None, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
229 else: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
230 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
|
231 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
232 return vcard_dict |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
233 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
234 async def getVCardElement(self, client, entity_jid): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
235 """Retrieve domish.Element of a VCard |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
236 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
237 @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
|
238 @raise DataError: we got an invalid answer |
43 | 239 """ |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
240 iq_elt = client.IQ("get") |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
241 iq_elt["from"] = client.jid.full() |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
242 iq_elt["to"] = entity_jid.full() |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
243 iq_elt.addElement("vCard", NS_VCARD) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
244 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
|
245 try: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
246 return next(iq_ret_elt.elements(NS_VCARD, "vCard")) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
247 except StopIteration: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
248 log.warning(_( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
249 "vCard element not found for {entity_jid}: {xml}" |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
250 ).format(entity_jid=entity_jid, xml=iq_ret_elt.toXml())) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
251 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
|
252 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
253 async def updateVCardElt(self, client, entity_jid, to_replace): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
254 """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
|
255 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
256 @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
|
257 """ |
cffa50c9f26b
plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents:
2145
diff
changeset
|
258 try: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
259 # we first check if a vcard already exists, to keep data |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
260 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
|
261 except error.StanzaError as e: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
262 if e.condition == "item-not-found": |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
263 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
|
264 else: |
cffa50c9f26b
plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents:
2145
diff
changeset
|
265 raise e |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
266 except exceptions.DataError: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
267 vcard_elt = domish.Element((NS_VCARD, "vCard")) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
268 else: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
269 # 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
|
270 for elt_name in to_replace: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
271 try: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
272 elt = next(vcard_elt.elements(NS_VCARD, elt_name)) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
273 except StopIteration: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
274 pass |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
275 else: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
276 vcard_elt.children.remove(elt) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
277 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
278 return vcard_elt |
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 async def getCard(self, client, entity_jid): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
281 """Ask server for VCard |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
282 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
283 @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
|
284 @result(dict): vCard data |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
285 """ |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
286 entity_jid = self._i.getIdentityJid(client, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
287 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
|
288 try: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
289 vcard_elt = await self.getVCardElement(client, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
290 except exceptions.DataError: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
291 self._i.update(client, "avatar", None, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
292 except Exception as e: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
293 log.warning(_( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
294 "Can't get vCard for {entity_jid}: {e}" |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
295 ).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
|
296 else: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
297 log.debug(_("VCard found")) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
298 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
|
299 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
300 async def getAvatar(self, client, entity_jid): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
301 """Get avatar full path or hash |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
302 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
303 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
|
304 @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
|
305 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
306 """ |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
307 entity_jid = self._i.getIdentityJid(client, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
308 hashes_cache = client._xep_0054_avatar_hashes |
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: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
312 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
|
313 vcard = await self.getCard(client, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
314 if vcard is None: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
315 return None |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
316 avatar_hash = hashes_cache[entity_jid.full()] |
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 if not avatar_hash: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
319 return None |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
320 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
321 avatar_cache = self.host.common_cache.getMetadata(avatar_hash) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
322 if avatar_cache is None: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
323 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
|
324 vcard = await self.getCard(client, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
325 if vcard is None: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
326 return None |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
327 avatar_cache = self.host.common_cache.getMetadata(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 return self._i.avatarBuildMetadata( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
330 avatar_cache['path'], avatar_cache['mime_type'], avatar_hash) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
331 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
332 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
|
333 # XXX: this method is executed in a separate thread |
562
0bb2e0d1c878
core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents:
560
diff
changeset
|
334 try: |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
335 img = Image.open(avatar_data['path']) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
336 except IOError as e: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
337 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
|
338 |
1081
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
339 if img.size != AVATAR_DIM: |
2506
516bf5309517
plugin XEP-0054: removed Image.ANTIALIAS filter:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
340 img.thumbnail(AVATAR_DIM) |
1081
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
341 if img.size[0] != img.size[1]: # we need to crop first |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
342 left, upper = (0, 0) |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
343 right, lower = img.size |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
344 offset = abs(right - lower) / 2 |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
345 if right == min(img.size): |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
346 upper += offset |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
347 lower -= offset |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
348 else: |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
349 left += offset |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
350 right -= offset |
5d89fecdf667
plugin XEP-0054: crop uploaded avatar to get a square
souliane <souliane@mailoo.org>
parents:
1075
diff
changeset
|
351 img = img.crop((left, upper, right, lower)) |
3040 | 352 img_buf = io.BytesIO() |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
353 img.save(img_buf, "PNG") |
562
0bb2e0d1c878
core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents:
560
diff
changeset
|
354 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
355 photo_elt = vcard_elt.addElement("PHOTO") |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
356 photo_elt.addElement("TYPE", content="image/png") |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
357 image_b64 = b64encode(img_buf.getvalue()).decode() |
3040 | 358 photo_elt.addElement("BINVAL", content=image_b64) |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
359 image_hash = sha1(img_buf.getvalue()).hexdigest() |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
360 with self.host.common_cache.cacheData( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
361 PLUGIN_INFO["import_name"], image_hash, "image/png" |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
362 ) as f: |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
363 f.write(img_buf.getvalue()) |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
364 avatar_data['path'] = Path(f.name) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
365 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
|
366 return image_hash |
562
0bb2e0d1c878
core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents:
560
diff
changeset
|
367 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
368 async def setAvatar(self, client, avatar_data, entity): |
562
0bb2e0d1c878
core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents:
560
diff
changeset
|
369 """Set avatar of the profile |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
370 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
371 @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
|
372 IDENTITY plugin. |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
373 @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
|
374 """ |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
375 vcard_elt = await self.updateVCardElt(client, entity, ['PHOTO']) |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
376 |
2252
cffa50c9f26b
plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents:
2145
diff
changeset
|
377 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
|
378 iq_elt.addChild(vcard_elt) |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
379 await threads.deferToThread( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
380 self._buildSetAvatar, client, vcard_elt, avatar_data |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
381 ) |
2252
cffa50c9f26b
plugin XEP-0054: nick handling + don't remove data on avatar set
Goffi <goffi@goffi.org>
parents:
2145
diff
changeset
|
382 # image is now at the right size/format |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
383 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
384 await iq_elt.send() |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
385 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
386 # FIXME: should send the current presence, not always "available" ! |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
387 await client.presence.available() |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
388 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
389 async def getNicknames(self, client, entity): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
390 """get nick from cache, or check vCard |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
391 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
392 @param entity(jid.JID): entity to get nick from |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
393 @return(list[str]): nicknames found |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
394 """ |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
395 vcard_data = await self.getCard(client, entity) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
396 try: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
397 return [vcard_data['nickname']] |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
398 except (KeyError, TypeError): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
399 return [] |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
400 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
401 async def setNicknames(self, client, nicknames, entity): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
402 """Update our vCard and set a nickname |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
403 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
404 @param nicknames(list[str]): new nicknames to use |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
405 only first item of this list will be used here |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
406 """ |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
407 nick = nicknames[0].strip() |
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 vcard_elt = await self.updateVCardElt(client, entity, ['NICKNAME']) |
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 if nick: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
412 vcard_elt.addElement((NS_VCARD, "NICKNAME"), content=nick) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
413 iq_elt = client.IQ() |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
414 iq_elt.addChild(vcard_elt) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
415 await iq_elt.send() |
562
0bb2e0d1c878
core, plugin XEP-0054: avatar upload:
Goffi <goffi@goffi.org>
parents:
560
diff
changeset
|
416 |
64 | 417 |
3028 | 418 @implementer(iwokkel.IDisco) |
64 | 419 class XEP_0054_handler(XMPPHandler): |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
420 |
64 | 421 def __init__(self, plugin_parent): |
422 self.plugin_parent = plugin_parent | |
423 self.host = plugin_parent.host | |
424 | |
425 def connectionInitialized(self): | |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
426 self.xmlstream.addObserver(VCARD_UPDATE, self._update) |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
427 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
428 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): |
64 | 429 return [disco.DiscoFeature(NS_VCARD)] |
430 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
431 def getDiscoItems(self, requestor, target, nodeIdentifier=""): |
64 | 432 return [] |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
433 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
434 def _checkAvatarHash(self, client, entity, given_hash): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
435 """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
|
436 # 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
|
437 # TODO: try to avoid re-requesting avatar in this case |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
438 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
|
439 if computed_hash != given_hash: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
440 log.warning( |
3028 | 441 "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
|
442 "computed: {computed}\ngiven: {given}".format( |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
443 entity=entity, computed=computed_hash, given=given_hash |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
444 ) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
445 ) |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
446 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
447 async def update(self, presence): |
1317
bd69d341d969
plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents:
1315
diff
changeset
|
448 """Called on <presence/> stanza with vcard data |
bd69d341d969
plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents:
1315
diff
changeset
|
449 |
bd69d341d969
plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents:
1315
diff
changeset
|
450 Check for avatar information, and get VCard if needed |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
451 @param presence(domish.Element): <presence/> stanza |
48 | 452 """ |
2123
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
453 client = self.parent |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
454 entity_jid = self.plugin_parent._i.getIdentityJid( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
455 client, jid.JID(presence["from"])) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
456 |
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
|
457 try: |
3028 | 458 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
|
459 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
|
460 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
|
461 |
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
|
462 try: |
3028 | 463 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
|
464 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
|
465 return |
1317
bd69d341d969
plugin xep-0054: various improvments on avatars management:
Goffi <goffi@goffi.org>
parents:
1315
diff
changeset
|
466 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
467 new_hash = str(photo_elt).strip() |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
468 if new_hash == HASH_SHA1_EMPTY: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
469 new_hash = "" |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
470 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
471 hashes_cache = client._xep_0054_avatar_hashes |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
472 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
473 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
|
474 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
475 if old_hash == new_hash: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
476 # no change, we can return… |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
477 if new_hash: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
478 # …but we double check that avatar is in cache |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
479 avatar_cache = self.host.common_cache.getMetadata(new_hash) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
480 if avatar_cache is None: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
481 log.debug( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
482 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
|
483 f"it" |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
484 ) |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
485 # getCard will put the avatar in cache |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
486 await self.plugin_parent.getCard(client, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
487 else: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
488 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
|
489 return |
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
490 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
491 if new_hash is None: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
492 # 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
|
493 new_hash = "" |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
494 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
495 await hashes_cache.aset(entity_jid.full(), new_hash) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
496 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
497 if not new_hash: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
498 await self.plugin_parent._i.update( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
499 client, "avatar", None, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
500 # 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
|
501 return |
c42aab22c2c0
plugin XEP-0054, quick frontend(app): various improvments:
Goffi <goffi@goffi.org>
parents:
2072
diff
changeset
|
502 |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
503 avatar_cache = self.host.common_cache.getMetadata(new_hash) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
504 if avatar_cache is not None: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
505 log.debug( |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
506 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
|
507 ) |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
508 await self.plugin_parent._i.update( |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
509 client, |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
510 "avatar", |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
511 { |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
512 'path': avatar_cache['path'], |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
513 'media_type': avatar_cache['mime_type'], |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
514 'cache_uid': new_hash, |
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 entity_jid |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
517 ) |
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
|
518 else: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
519 log.debug( |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
520 "New avatar found for [{entity_jid}], requesting vcard" |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2581
diff
changeset
|
521 ) |
3254
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
522 vcard = await self.plugin_parent.getCard(client, entity_jid) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
523 if vcard is None: |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
524 log.warning(f"Unexpected empty vCard for {entity_jid}") |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
525 return |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
526 await self._checkAvatarHash(client, entity_jid, new_hash) |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
527 |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
528 def _update(self, presence): |
6cf4bd6972c2
core, frontends: avatar refactoring:
Goffi <goffi@goffi.org>
parents:
3199
diff
changeset
|
529 defer.ensureDeferred(self.update(presence)) |