Mercurial > libervia-backend
annotate libervia/backend/plugins/plugin_xep_0447.py @ 4095:684ba556a617
core (memory/sqla_mapping): fix legacy pickled values:
folloing packages refactoring, legacy pickled values could not be unpickled (due to use of
old classes). This temporary workaround fix it, but the right thing to do will be to move
from pickle to JSON at some point.
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 12 Jun 2023 14:57:27 +0200 |
parents | 4b842c1fb686 |
children | 0d7bb4df2343 |
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"] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
69 self._attach.register( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
70 self.can_handle_attachment, self.attach, priority=1000 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
71 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
72 self.register_source_handler( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
73 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
|
74 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
75 host.plugins["DOWNLOAD"].register_download_handler(self._u.namespace, self.download) |
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( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
79 self, namespace: str, element_name: str, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
80 callback: Callable[[domish.Element], Dict[str, Any]], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
81 encrypted: bool = False |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
82 ) -> None: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
83 """Register a handler for file source |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
84 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
85 @param namespace: namespace of the element supported |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
86 @param element_name: name of the element supported |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
87 @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
|
88 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
|
89 @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
|
90 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
|
91 """ |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
92 key = (namespace, element_name) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
93 if key in self._sources_handlers: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
94 raise exceptions.ConflictError( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
95 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
|
96 f"name {element_name!r}" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
97 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
98 self._sources_handlers[key] = SourceHandler(callback, encrypted) |
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 async def download( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
101 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
102 client: SatXMPPEntity, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
103 attachment: Dict[str, Any], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
104 source: Dict[str, Any], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
105 dest_path: Union[Path, str], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
106 extra: Optional[Dict[str, Any]] = None |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
107 ) -> Tuple[str, defer.Deferred]: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
108 # TODO: handle url-data headers |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
109 if extra is None: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
110 extra = {} |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
111 try: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
112 download_url = source["url"] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
113 except KeyError: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
114 raise ValueError(f"{source} has missing URL") |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
115 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
116 if extra.get('ignore_tls_errors', False): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
117 log.warning( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
118 "TLS certificate check disabled, this is highly insecure" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
119 ) |
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) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
128 file_size = int(head_data.headers.getRawHeaders('content-length')[0]) |
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", |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
135 size = file_size, |
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( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
160 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
161 children: Optional[List[domish.Element]] = None |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
162 ) -> domish.Element: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
163 """Generate <sources> element""" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
164 sources_elt = domish.Element((NS_SFS, "sources")) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
165 if children: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
166 for child in children: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
167 sources_elt.addChild(child) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
168 return sources_elt |
3897
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
169 |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
170 def get_file_sharing_elt( |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
171 self, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
172 sources: List[Dict[str, Any]], |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
173 disposition: Optional[str] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
174 name: Optional[str] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
175 media_type: Optional[str] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
176 desc: Optional[str] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
177 size: Optional[int] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
178 file_hash: Optional[Tuple[str, str]] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
179 date: Optional[Union[float, int]] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
180 width: Optional[int] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
181 height: Optional[int] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
182 length: Optional[int] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
183 thumbnail: Optional[str] = None, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
184 **kwargs, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
185 ) -> domish.Element: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
186 """Generate the <file-sharing/> element |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
187 |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
188 @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
|
189 @return: ``<sfs/>`` element |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
190 """ |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
191 file_sharing_elt = domish.Element((NS_SFS, "file-sharing")) |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
192 if disposition is not None: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
193 file_sharing_elt["disposition"] = disposition |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
194 if media_type is None and name: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
195 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
|
196 file_sharing_elt.addChild( |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
197 self._m.get_file_metadata_elt( |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
198 name=name, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
199 media_type=media_type, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
200 desc=desc, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
201 size=size, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
202 file_hash=file_hash, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
203 date=date, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
204 width=width, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
205 height=height, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
206 length=length, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
207 thumbnail=thumbnail, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
208 ) |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
209 ) |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
210 sources_elt = self.get_sources_elt() |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
211 file_sharing_elt.addChild(sources_elt) |
3897
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
212 for source_data in sources: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
213 if "url" in source_data: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
214 sources_elt.addChild( |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
215 self._u.get_url_data_elt(**source_data) |
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 else: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
218 raise NotImplementedError( |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
219 f"source data not implemented: {source_data}" |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
220 ) |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
221 |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
222 return file_sharing_elt |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
223 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
224 def parse_sources_elt( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
225 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
226 sources_elt: domish.Element |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
227 ) -> List[Dict[str, Any]]: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
228 """Parse <sources/> element |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
229 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
230 @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
|
231 @return: list of found sources data |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
232 @raise: exceptions.NotFound: Can't find <sources/> element |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
233 """ |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
234 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
|
235 try: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
236 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
|
237 except StopIteration: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
238 raise exceptions.NotFound( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
239 f"<sources/> element is missing: {sources_elt.toXml()}") |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
240 sources = [] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
241 for elt in sources_elt.elements(): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
242 if not elt.uri: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
243 log.warning("ignoring source element {elt.toXml()}") |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
244 continue |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
245 key = (elt.uri, elt.name) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
246 try: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
247 source_handler = self._sources_handlers[key] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
248 except KeyError: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
249 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
|
250 continue |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
251 else: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
252 source_data = source_handler.callback(elt) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
253 if source_handler.encrypted: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
254 source_data[C.MESS_KEY_ENCRYPTED] = True |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
255 if "type" not in source_data: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
256 source_data["type"] = elt.uri |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
257 sources.append(source_data) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
258 return sources |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
259 |
3897
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
260 def parse_file_sharing_elt( |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
261 self, |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
262 file_sharing_elt: domish.Element |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
263 ) -> Dict[str, Any]: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
264 """Parse <file-sharing/> element and return file-sharing data |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
265 |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
266 @param file_sharing_elt: <file-sharing/> element |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
267 @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
|
268 [get_file_sharing_elt] parameters |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
269 """ |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
270 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
|
271 try: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
272 file_sharing_elt = next( |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
273 file_sharing_elt.elements(NS_SFS, "file-sharing") |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
274 ) |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
275 except StopIteration: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
276 raise exceptions.NotFound |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
277 try: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
278 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
|
279 except exceptions.NotFound: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
280 data = {} |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
281 disposition = file_sharing_elt.getAttribute("disposition") |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
282 if disposition is not None: |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
283 data["disposition"] = disposition |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
284 try: |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
285 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
|
286 except exceptions.NotFound as e: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
287 raise ValueError(str(e)) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
288 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
289 return data |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
290 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
291 def _add_file_sharing_attachments( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
292 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
293 client: SatXMPPEntity, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
294 message_elt: domish.Element, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
295 data: Dict[str, Any] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
296 ) -> Dict[str, Any]: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
297 """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
|
298 # 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
|
299 # 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
|
300 # <file-sharing> element in a message. |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
301 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
|
302 attachment = self.parse_file_sharing_elt(message_elt) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
303 |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
304 if any( |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
305 s.get(C.MESS_KEY_ENCRYPTED, False) |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
306 for s in attachment["sources"] |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
307 ) and client.encryption.isEncrypted(data): |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
308 # 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
|
309 # 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
|
310 # unencrypted channel is like having no encryption at all. |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
311 attachment[C.MESS_KEY_ENCRYPTED] = True |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
312 |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
313 attachments = data['extra'].setdefault(C.KEY_ATTACHMENTS, []) |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
314 attachments.append(attachment) |
3897
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
315 |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
316 return data |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
317 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
318 async def attach(self, client, data): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
319 # 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
|
320 # to send each file in a separate message |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
321 attachments = data["extra"][C.KEY_ATTACHMENTS] |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
322 if not data['message'] or data['message'] == {'': ''}: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
323 extra_attachments = attachments[1:] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
324 del attachments[1:] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
325 else: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
326 # 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
|
327 extra_attachments = attachments[:] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
328 attachments.clear() |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
329 del data["extra"][C.KEY_ATTACHMENTS] |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
330 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
331 if attachments: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
332 if len(attachments) > 1: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
333 raise exceptions.InternalError( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
334 "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
|
335 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
336 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
|
337 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
|
338 for attachment in attachments: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
339 try: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
340 file_hash = (attachment["hash_algo"], attachment["hash"]) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
341 except KeyError: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
342 file_hash = None |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
343 file_sharing_elt = self.get_file_sharing_elt( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
344 [{"url": attachment["url"]}], |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
345 name=attachment.get("name"), |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
346 size=attachment.get("size"), |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
347 desc=attachment.get("desc"), |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
348 media_type=attachment.get("media_type"), |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
349 file_hash=file_hash |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
350 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
351 data["xml"].addChild(file_sharing_elt) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
352 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
353 for attachment in extra_attachments: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
354 # 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
|
355 await client.sendMessage( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
356 to_jid=data['to'], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
357 message={'': ''}, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
358 subject=data['subject'], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
359 mess_type=data['type'], |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
360 extra={C.KEY_ATTACHMENTS: [attachment]}, |
3922
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 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
363 if ((not data['extra'] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
364 and (not data['message'] or data['message'] == {'': ''}) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
365 and not data['subject'])): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
366 # 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
|
367 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
|
368 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
369 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
|
370 # 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
|
371 # 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
|
372 # attachment |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
373 post_treat.addCallback( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
374 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
|
375 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
376 return True |