annotate libervia/backend/plugins/plugin_xep_0447.py @ 4278:240d8b7ad906

component Conferences: implementation of SFU component to make multi-party A/V conferences: This component wrap `Galène` SFU and translate its signaling to XMPP Jingle in both direction. rel 445
author Goffi <goffi@goffi.org>
date Fri, 05 Jul 2024 17:18:37 +0200
parents 0d7bb4df2343
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Copyright (C) 2009-2022 Jérôme Poisson (goffi@goffi.org)
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
4
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 # This program is free software: you can redistribute it and/or modify
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # it under the terms of the GNU Affero General Public License as published by
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # the Free Software Foundation, either version 3 of the License, or
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # (at your option) any later version.
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
9
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # This program is distributed in the hope that it will be useful,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # GNU Affero General Public License for more details.
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
14
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # You should have received a copy of the GNU Affero General Public License
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
17
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
18 from collections import namedtuple
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
19 from functools import partial
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
20 import mimetypes
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
21 from pathlib import Path
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
22 from typing import Any, Callable, Dict, List, Optional, Tuple, Union
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
23
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
24 import treq
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
25 from twisted.internet import defer
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from twisted.words.xish import domish
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
27
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
28 from libervia.backend.core import exceptions
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
29 from libervia.backend.core.constants import Const as C
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
30 from libervia.backend.core.core_types import SatXMPPEntity
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
31 from libervia.backend.core.i18n import _
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
32 from libervia.backend.core.log import getLogger
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
33 from libervia.backend.tools import stream
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
34 from libervia.backend.tools.web import treq_client_no_ssl
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
35
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 log = getLogger(__name__)
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 PLUGIN_INFO = {
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 C.PI_NAME: "Stateless File Sharing",
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 C.PI_IMPORT_NAME: "XEP-0447",
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 C.PI_TYPE: "XEP",
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 C.PI_MODES: C.PLUG_MODE_BOTH,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 C.PI_PROTOCOLS: ["XEP-0447"],
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
45 C.PI_DEPENDENCIES: ["XEP-0103", "XEP-0334", "XEP-0446", "ATTACH", "DOWNLOAD"],
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
46 C.PI_RECOMMENDATIONS: ["XEP-0363"],
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 C.PI_MAIN: "XEP_0447",
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 C.PI_HANDLER: "no",
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 C.PI_DESCRIPTION: _("""Implementation of XEP-0447 (Stateless File Sharing)"""),
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 }
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
51
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 NS_SFS = "urn:xmpp:sfs:0"
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
53 SourceHandler = namedtuple("SourceHandler", ["callback", "encrypted"])
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
54
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
55
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 class XEP_0447:
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 namespace = NS_SFS
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
58
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 def __init__(self, host):
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
60 self.host = host
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 log.info(_("XEP-0447 (Stateless File Sharing) plugin initialization"))
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
62 host.register_namespace("sfs", NS_SFS)
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
63 self._sources_handlers = {}
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 self._u = host.plugins["XEP-0103"]
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
65 self._hints = host.plugins["XEP-0334"]
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 self._m = host.plugins["XEP-0446"]
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
67 self._http_upload = host.plugins.get("XEP-0363")
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
68 self._attach = host.plugins["ATTACH"]
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
69 self._attach.register(self.can_handle_attachment, self.attach, priority=1000)
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
70 self.register_source_handler(
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
71 self._u.namespace, "url-data", self._u.parse_url_data_elt
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
72 )
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
73 host.plugins["DOWNLOAD"].register_download_handler(
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
74 self._u.namespace, self.download
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
75 )
4051
c23cad65ae99 core: renamed `messageReceived` trigger to `message_received`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
76 host.trigger.add("message_received", self._message_received_trigger)
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
77
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
78 def register_source_handler(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
79 self,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
80 namespace: str,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
81 element_name: str,
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
82 callback: Callable[[domish.Element], Dict[str, Any]],
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
83 encrypted: bool = False,
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
84 ) -> None:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
85 """Register a handler for file source
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
86
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
87 @param namespace: namespace of the element supported
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
88 @param element_name: name of the element supported
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
89 @param callback: method to call to parse the element
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
90 get the matching element as argument, must return the parsed data
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
91 @param encrypted: if True, the source is encrypted (the transmitting channel
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
92 should then be end2end encrypted to avoir leaking decrypting data to servers).
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
93 """
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
94 key = (namespace, element_name)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
95 if key in self._sources_handlers:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
96 raise exceptions.ConflictError(
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
97 f"There is already a resource handler for namespace {namespace!r} and "
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
98 f"name {element_name!r}"
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
99 )
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
100 self._sources_handlers[key] = SourceHandler(callback, encrypted)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
101
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
102 async def download(
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
103 self,
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
104 client: SatXMPPEntity,
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
105 attachment: Dict[str, Any],
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
106 source: Dict[str, Any],
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
107 dest_path: Union[Path, str],
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
108 extra: Optional[Dict[str, Any]] = None,
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
109 ) -> Tuple[str, defer.Deferred]:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
110 # TODO: handle url-data headers
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
111 if extra is None:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
112 extra = {}
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
113 try:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
114 download_url = source["url"]
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
115 except KeyError:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
116 raise ValueError(f"{source} has missing URL")
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
117
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
118 if extra.get("ignore_tls_errors", False):
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
119 log.warning("TLS certificate check disabled, this is highly insecure")
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
120 treq_client = treq_client_no_ssl
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
121 else:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
122 treq_client = treq
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
123
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
124 try:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
125 file_size = int(attachment["size"])
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
126 except (KeyError, ValueError):
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
127 head_data = await treq_client.head(download_url)
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
128 file_size = int(head_data.headers.getRawHeaders("content-length")[0])
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
129
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
130 file_obj = stream.SatFile(
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
131 self.host,
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
132 client,
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
133 dest_path,
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
134 mode="wb",
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
135 size=file_size,
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
136 )
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
137
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
138 progress_id = file_obj.uid
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
139
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
140 resp = await treq_client.get(download_url, unbuffered=True)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
141 if resp.code == 200:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
142 d = treq.collect(resp, file_obj.write)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
143 d.addCallback(lambda __: file_obj.close())
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
144 else:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
145 d = defer.Deferred()
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
146 self.host.plugins["DOWNLOAD"].errback_download(file_obj, d, resp)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
147 return progress_id, d
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
148
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
149 async def can_handle_attachment(self, client, data):
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
150 if self._http_upload is None:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
151 return False
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
152 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
153 await self._http_upload.get_http_upload_entity(client)
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
154 except exceptions.NotFound:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
155 return False
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
156 else:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
157 return True
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
158
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
159 def get_sources_elt(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
160 self, children: Optional[List[domish.Element]] = None
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
161 ) -> domish.Element:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
162 """Generate <sources> element"""
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
163 sources_elt = domish.Element((NS_SFS, "sources"))
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
164 if children:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
165 for child in children:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
166 sources_elt.addChild(child)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
167 return sources_elt
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
168
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 def get_file_sharing_elt(
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 self,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 sources: List[Dict[str, Any]],
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 disposition: Optional[str] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 name: Optional[str] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 media_type: Optional[str] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 desc: Optional[str] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 size: Optional[int] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 file_hash: Optional[Tuple[str, str]] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 date: Optional[Union[float, int]] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 width: Optional[int] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 height: Optional[int] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 length: Optional[int] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 thumbnail: Optional[str] = None,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 **kwargs,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 ) -> domish.Element:
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 """Generate the <file-sharing/> element
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
186
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 @param extra: extra metadata describing how to access the URL
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 @return: ``<sfs/>`` element
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 """
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 file_sharing_elt = domish.Element((NS_SFS, "file-sharing"))
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 if disposition is not None:
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 file_sharing_elt["disposition"] = disposition
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
193 if media_type is None and name:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
194 media_type = mimetypes.guess_type(name, strict=False)[0]
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 file_sharing_elt.addChild(
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 self._m.get_file_metadata_elt(
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 name=name,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 media_type=media_type,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 desc=desc,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 size=size,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 file_hash=file_hash,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 date=date,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 width=width,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 height=height,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 length=length,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 thumbnail=thumbnail,
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 )
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 )
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
209 sources_elt = self.get_sources_elt()
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
210 file_sharing_elt.addChild(sources_elt)
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 for source_data in sources:
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 if "url" in source_data:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
213 sources_elt.addChild(self._u.get_url_data_elt(**source_data))
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 else:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
215 raise NotImplementedError(f"source data not implemented: {source_data}")
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
216
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 return file_sharing_elt
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
218
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
219 def parse_sources_elt(self, sources_elt: domish.Element) -> List[Dict[str, Any]]:
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
220 """Parse <sources/> element
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
221
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
222 @param sources_elt: <sources/> element, or a direct parent element
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
223 @return: list of found sources data
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
224 @raise: exceptions.NotFound: Can't find <sources/> element
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
225 """
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
226 if sources_elt.name != "sources" or sources_elt.uri != NS_SFS:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
227 try:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
228 sources_elt = next(sources_elt.elements(NS_SFS, "sources"))
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
229 except StopIteration:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
230 raise exceptions.NotFound(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
231 f"<sources/> element is missing: {sources_elt.toXml()}"
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
232 )
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
233 sources = []
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
234 for elt in sources_elt.elements():
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
235 if not elt.uri:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
236 log.warning("ignoring source element {elt.toXml()}")
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
237 continue
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
238 key = (elt.uri, elt.name)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
239 try:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
240 source_handler = self._sources_handlers[key]
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
241 except KeyError:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
242 log.warning(f"unmanaged file sharing element: {elt.toXml}")
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
243 continue
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
244 else:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
245 source_data = source_handler.callback(elt)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
246 if source_handler.encrypted:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
247 source_data[C.MESS_KEY_ENCRYPTED] = True
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
248 if "type" not in source_data:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
249 source_data["type"] = elt.uri
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
250 sources.append(source_data)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
251 return sources
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
252
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
253 def parse_file_sharing_elt(self, file_sharing_elt: domish.Element) -> Dict[str, Any]:
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 """Parse <file-sharing/> element and return file-sharing data
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
255
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 @param file_sharing_elt: <file-sharing/> element
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
257 @return: file-sharing data. It a dict whose keys correspond to
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 [get_file_sharing_elt] parameters
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 """
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
260 if file_sharing_elt.name != "file-sharing" or file_sharing_elt.uri != NS_SFS:
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
261 try:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
262 file_sharing_elt = next(file_sharing_elt.elements(NS_SFS, "file-sharing"))
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 except StopIteration:
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 raise exceptions.NotFound
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 try:
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
266 data = self._m.parse_file_metadata_elt(file_sharing_elt)
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
267 except exceptions.NotFound:
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 data = {}
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
269 disposition = file_sharing_elt.getAttribute("disposition")
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
270 if disposition is not None:
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
271 data["disposition"] = disposition
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
272 try:
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
273 data["sources"] = self.parse_sources_elt(file_sharing_elt)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
274 except exceptions.NotFound as e:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
275 raise ValueError(str(e))
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
276
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
277 return data
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
278
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
279 def _add_file_sharing_attachments(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
280 self, client: SatXMPPEntity, message_elt: domish.Element, data: Dict[str, Any]
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
281 ) -> Dict[str, Any]:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
282 """Check <message> for a shared file, and add it as an attachment"""
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
283 # XXX: XEP-0447 doesn't support several attachments in a single message, for now
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
284 # however that should be fixed in future version, and so we accept several
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
285 # <file-sharing> element in a message.
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
286 for file_sharing_elt in message_elt.elements(NS_SFS, "file-sharing"):
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
287 attachment = self.parse_file_sharing_elt(message_elt)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
288
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
289 if any(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
290 s.get(C.MESS_KEY_ENCRYPTED, False) for s in attachment["sources"]
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
291 ) and client.encryption.isEncrypted(data):
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
292 # we don't add the encrypted flag if the message itself is not encrypted,
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
293 # because the decryption key is part of the link, so sending it over
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
294 # unencrypted channel is like having no encryption at all.
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
295 attachment[C.MESS_KEY_ENCRYPTED] = True
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
296
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
297 attachments = data["extra"].setdefault(C.KEY_ATTACHMENTS, [])
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
298 attachments.append(attachment)
3897
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
299
4b7106eede0c plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
300 return data
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
301
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
302 async def attach(self, client, data):
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
303 # XXX: for now, XEP-0447 only allow to send one file per <message/>, thus we need
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
304 # to send each file in a separate message
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
305 attachments = data["extra"][C.KEY_ATTACHMENTS]
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
306 if not data["message"] or data["message"] == {"": ""}:
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
307 extra_attachments = attachments[1:]
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
308 del attachments[1:]
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
309 else:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
310 # we have a message, we must send first attachment separately
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
311 extra_attachments = attachments[:]
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
312 attachments.clear()
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
313 del data["extra"][C.KEY_ATTACHMENTS]
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
314
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
315 if attachments:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
316 if len(attachments) > 1:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
317 raise exceptions.InternalError(
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
318 "There should not be more that one attachment at this point"
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
319 )
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
320 await self._attach.upload_files(client, data)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
321 self._hints.add_hint_elements(data["xml"], [self._hints.HINT_STORE])
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
322 for attachment in attachments:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
323 try:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
324 file_hash = (attachment["hash_algo"], attachment["hash"])
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
325 except KeyError:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
326 file_hash = None
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
327 file_sharing_elt = self.get_file_sharing_elt(
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
328 [{"url": attachment["url"]}],
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
329 name=attachment.get("name"),
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
330 size=attachment.get("size"),
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
331 desc=attachment.get("desc"),
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
332 media_type=attachment.get("media_type"),
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
333 file_hash=file_hash,
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
334 )
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
335 data["xml"].addChild(file_sharing_elt)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
336
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
337 for attachment in extra_attachments:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
338 # we send all remaining attachment in a separate message
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
339 await client.sendMessage(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
340 to_jid=data["to"],
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
341 message={"": ""},
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
342 subject=data["subject"],
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
343 mess_type=data["type"],
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
344 extra={C.KEY_ATTACHMENTS: [attachment]},
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
345 )
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
346
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
347 if (
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
348 not data["extra"]
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
349 and (not data["message"] or data["message"] == {"": ""})
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
350 and not data["subject"]
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
351 ):
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
352 # nothing left to send, we can cancel the message
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
353 raise exceptions.CancelError("Cancelled by XEP_0447 attachment handling")
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
354
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
355 def _message_received_trigger(self, client, message_elt, post_treat):
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
356 # we use a post_treat callback instead of "message_parse" trigger because we need
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
357 # to check if the "encrypted" flag is set to decide if we add the same flag to the
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
358 # attachment
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
359 post_treat.addCallback(
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
360 partial(self._add_file_sharing_attachments, client, message_elt)
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
361 )
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3897
diff changeset
362 return True