Mercurial > libervia-backend
annotate libervia/backend/plugins/plugin_xep_0447.py @ 4320:9658c534287e
plugin XEP-0215, XEP-0376: fix bad calls to `hasFeature`:
`hasFeature` was called like blocking code, missing the `await`. This has been fixed, and
is now using the `memory.disco.has_feature` version.
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 30 Sep 2024 14:14:38 +0200 |
parents | 0d7bb4df2343 |
children |
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 |