annotate libervia/backend/plugins/plugin_xep_0292.py @ 4306:94e0968987cd

plugin XEP-0033: code modernisation, improve delivery, data validation: - Code has been rewritten using Pydantic models and `async` coroutines for data validation and cleaner element parsing/generation. - Delivery has been completely rewritten. It now works even if server doesn't support multicast, and send to local multicast service first. Delivering to local multicast service first is due to bad support of XEP-0033 in server (notably Prosody which has an incomplete implementation), and the current impossibility to detect if a sub-domain service handles fully multicast or only for local domains. This is a workaround to have a good balance between backward compatilibity and use of bandwith, and to make it work with the incoming email gateway implementation (the gateway will only deliver to entities of its own domain). - disco feature checking now uses `async` corountines. `host` implementation still use Deferred return values for compatibility with legacy code. rel 450
author Goffi <goffi@goffi.org>
date Thu, 26 Sep 2024 16:12:01 +0200
parents 0d7bb4df2343
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia plugin for XEP-0292
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2022 Jérôme Poisson (goffi@goffi.org)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 from typing import List, Dict, Union, Any, Optional
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 from functools import partial
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
21
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from twisted.words.protocols.jabber import jid
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from twisted.words.xish import domish
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from zope.interface import implementer
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from wokkel import disco, iwokkel
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
27
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
28 from libervia.backend.core.constants import Const as C
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
29 from libervia.backend.core.i18n import _
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
30 from libervia.backend.core.log import getLogger
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
31 from libervia.backend.core.core_types import SatXMPPEntity
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
32 from libervia.backend.core import exceptions
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
33 from libervia.backend.tools.common.async_utils import async_lru
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
34
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
35
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 log = getLogger(__name__)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 IMPORT_NAME = "XEP-0292"
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
39
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 PLUGIN_INFO = {
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 C.PI_NAME: "vCard4 Over XMPP",
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 C.PI_IMPORT_NAME: IMPORT_NAME,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 C.PI_TYPE: C.PLUG_TYPE_XEP,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 C.PI_MODES: C.PLUG_MODE_BOTH,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 C.PI_PROTOCOLS: ["XEP-0292"],
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 C.PI_DEPENDENCIES: ["IDENTITY", "XEP-0060", "XEP-0163"],
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 C.PI_MAIN: "XEP_0292",
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 C.PI_HANDLER: "yes",
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 C.PI_DESCRIPTION: _("""XEP-0292 (vCard4 Over XMPP) implementation"""),
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 }
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
51
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 NS_VCARD4 = "urn:ietf:params:xml:ns:vcard-4.0"
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 VCARD4_NODE = "urn:xmpp:vcard4"
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
54 text_fields = {"fn": "name", "nickname": "nicknames", "note": "description"}
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
55 text_fields_inv = {v: k for k, v in text_fields.items()}
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
56
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
57
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 class XEP_0292:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 namespace = NS_VCARD4
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 node = VCARD4_NODE
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
61
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 def __init__(self, host):
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 # XXX: as of XEP-0292 v0.11, there is a dedicated <IQ/> protocol in this XEP which
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 # should be used according to the XEP. Hovewer it feels like an outdated behaviour
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 # and other clients don't seem to use it. After discussing it on xsf@ MUC, it
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 # seems that implemeting the dedicated <IQ/> protocol is a waste of time, and thus
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 # it is not done here. It is expected that this dedicated protocol will be removed
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 # from a future version of the XEP.
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 log.info(_("vCard4 Over XMPP initialization"))
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
70 host.register_namespace("vcard4", NS_VCARD4)
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 self.host = host
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 self._p = host.plugins["XEP-0060"]
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
73 self._i = host.plugins["IDENTITY"]
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 self._i.register(
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 IMPORT_NAME,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
76 "nicknames",
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 partial(self.getValue, field="nicknames"),
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
78 partial(self.set_value, field="nicknames"),
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
79 priority=1000,
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 )
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 self._i.register(
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 IMPORT_NAME,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
83 "description",
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 partial(self.getValue, field="description"),
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
85 partial(self.set_value, field="description"),
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
86 priority=1000,
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 )
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
88
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
89 def get_handler(self, client):
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 return XEP_0292_Handler()
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
91
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
92 def vcard_2_dict(self, vcard_elt: domish.Element) -> Dict[str, Any]:
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 """Convert vcard element to equivalent identity metadata"""
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 vcard: Dict[str, Any] = {}
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
95
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 for metadata_elt in vcard_elt.elements():
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 # Text values
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 for source_field, dest_field in text_fields.items():
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 if metadata_elt.name == source_field:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 if metadata_elt.text is not None:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
101 dest_type = self._i.get_field_type(dest_field)
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 value = str(metadata_elt.text)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 if dest_type is str:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 if dest_field in vcard:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
105 vcard[dest_field] += value
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 else:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 vcard[dest_field] = value
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 elif dest_type is list:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 vcard.setdefault(dest_field, []).append(value)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 else:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 raise exceptions.InternalError(
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
112 f"unexpected dest_type: {dest_type!r}"
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 )
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 break
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 else:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 log.debug(
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 f"Following element is currently unmanaged: {metadata_elt.toXml()}"
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 )
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 return vcard
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
120
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
121 def dict_2_v_card(self, vcard: dict[str, Any]) -> domish.Element:
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 """Convert vcard metadata to vCard4 element"""
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 vcard_elt = domish.Element((NS_VCARD4, "vcard"))
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 for field, elt_name in text_fields_inv.items():
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 value = vcard.get(field)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 if value:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 if isinstance(value, str):
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 value = [value]
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 if isinstance(value, list):
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 for v in value:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 field_elt = vcard_elt.addElement(elt_name)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 field_elt.addElement("text", content=v)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 else:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
134 log.warning(f"ignoring unexpected value: {value!r}")
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
135
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 return vcard_elt
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
137
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 @async_lru(5)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
139 async def get_card(self, client: SatXMPPEntity, entity: jid.JID) -> dict:
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
141 items, metadata = await self._p.get_items(
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 client, entity, VCARD4_NODE, item_ids=["current"]
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 )
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 except exceptions.NotFound:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
145 log.info(f"No vCard node found for {entity}")
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 return {}
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 item_elt = items[0]
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 try:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 vcard_elt = next(item_elt.elements(NS_VCARD4, "vcard"))
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 except StopIteration:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 log.info(f"vCard element is not present for {entity}")
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 return {}
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
153
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
154 return self.vcard_2_dict(vcard_elt)
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
155
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
156 async def update_vcard_elt(
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
157 self,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 client: SatXMPPEntity,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 vcard_elt: domish.Element,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
160 entity: Optional[jid.JID] = None,
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 ) -> None:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 """Update VCard 4 of given entity, create node if doesn't already exist
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
163
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 @param vcard_elt: whole vCard element to update
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 @param entity: entity for which the vCard must be updated
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
166 None to update profile's own vCard
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 """
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 service = entity or client.jid.userhostJID()
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 node_options = {
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
171 self._p.OPT_PUBLISH_MODEL: self._p.PUBLISH_MODEL_PUBLISHERS,
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 }
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
173 await self._p.create_if_new_node(client, service, VCARD4_NODE, node_options)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
174 await self._p.send_item(
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 client, service, VCARD4_NODE, vcard_elt, item_id=self._p.ID_SINGLETON
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 )
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
177
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
178 async def update_v_card(
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 self,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 client: SatXMPPEntity,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 vcard: Dict[str, Any],
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 entity: Optional[jid.JID] = None,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 update: bool = True,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 ) -> None:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 """Update VCard 4 of given entity, create node if doesn't already exist
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
186
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 @param vcard: identity metadata
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 @param entity: entity for which the vCard must be updated
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 None to update profile's own vCard
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 @param update: if True, current vCard will be retrieved and updated with given
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 vcard (thus if False, `vcard` data will fully replace previous one).
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 """
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 service = entity or client.jid.userhostJID()
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 if update:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
195 current_vcard = await self.get_card(client, service)
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 current_vcard.update(vcard)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 vcard = current_vcard
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
198 vcard_elt = self.dict_2_v_card(vcard)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
199 await self.update_vcard_elt(client, vcard_elt, service)
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
200
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 async def getValue(
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 self,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 client: SatXMPPEntity,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 entity: jid.JID,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 field: str,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 ) -> Optional[Union[str, List[str]]]:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 """Return generic value
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
208
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 @param entity: entity from who the vCard comes
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 @param field: name of the field to get
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 This has to be a string field
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 @return request value
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
214 vcard_data = await self.get_card(client, entity)
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
215 return vcard_data.get(field)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
216
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
217 async def set_value(
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 self,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 client: SatXMPPEntity,
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 value: Union[str, List[str]],
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 entity: jid.JID,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
222 field: str,
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 ) -> None:
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 """Set generic value
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
225
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 @param entity: entity from who the vCard comes
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 @param field: name of the field to get
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 This has to be a string field
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 3819
diff changeset
230 await self.update_v_card(client, {field: value}, entity)
3819
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
231
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
232
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 @implementer(iwokkel.IDisco)
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 class XEP_0292_Handler(XMPPHandler):
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
235
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 def getDiscoInfo(self, requestor, service, nodeIdentifier=""):
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 return [disco.DiscoFeature(NS_VCARD4)]
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
238
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 def getDiscoItems(self, requestor, service, nodeIdentifier=""):
4f02e339d184 plugin XEP-0292: vCard4 Over XMPP implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 return []