Mercurial > libervia-backend
annotate sat/plugins/plugin_xep_0447.py @ 3942:a92eef737703
plugin XEP-0373: download public keys if they are not found in local storage:
public keys were only obtained from PEP notifications, however this wasn't working if the
entity was not in our roster.
Now if no public key is retrieved from local storage, the public key node is requested,
and an error is raised if nothing is found. This allows the use of OX with entities which
are not in roster.
rel 380
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 15 Oct 2022 20:38:33 +0200 |
parents | 0ff265725489 |
children | 78b5f356900c |
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 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
28 from sat.core import exceptions |
3897
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
29 from sat.core.constants import Const as C |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
30 from sat.core.core_types import SatXMPPEntity |
3897
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
31 from sat.core.i18n import _ |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
32 from sat.core.log import getLogger |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
33 from sat.tools import stream |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
34 from sat.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")) |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
62 host.registerNamespace("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) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
76 host.trigger.add("messageReceived", self._message_received_trigger) |
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: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
153 await self._http_upload.getHTTPUploadEntity(client) |
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 """ |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
270 if file_sharing_elt.name != "file-sharing": |
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""" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
298 # XXX: XEP-0447 doesn't support several attachments in a single message, thus only |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
299 # one attachment can be added |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
300 try: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
301 attachment = self.parse_file_sharing_elt(message_elt) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
302 except exceptions.NotFound: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
303 return data |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
304 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
305 if any( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
306 s.get(C.MESS_KEY_ENCRYPTED, False) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
307 for s in attachment["sources"] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
308 ) and client.encryption.isEncrypted(data): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
309 # we don't add the encrypted flag if the message itself is not encrypted, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
310 # because the decryption key is part of the link, so sending it over |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
311 # unencrypted channel is like having no encryption at all. |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
312 attachment[C.MESS_KEY_ENCRYPTED] = True |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
313 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
314 attachments = data['extra'].setdefault(C.MESS_KEY_ATTACHMENTS, []) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
315 attachments.append(attachment) |
3897
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
316 |
4b7106eede0c
plugin XEP-0447: Stateless File Sharing implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
317 return data |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
318 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
319 async def attach(self, client, data): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
320 # 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
|
321 # to send each file in a separate message |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
322 attachments = data["extra"][C.MESS_KEY_ATTACHMENTS] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
323 if not data['message'] or data['message'] == {'': ''}: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
324 extra_attachments = attachments[1:] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
325 del attachments[1:] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
326 else: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
327 # 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
|
328 extra_attachments = attachments[:] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
329 attachments.clear() |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
330 del data["extra"][C.MESS_KEY_ATTACHMENTS] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
331 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
332 if attachments: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
333 if len(attachments) > 1: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
334 raise exceptions.InternalError( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
335 "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
|
336 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
337 await self._attach.upload_files(client, data) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
338 self._hints.addHintElements(data["xml"], [self._hints.HINT_STORE]) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
339 for attachment in attachments: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
340 try: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
341 file_hash = (attachment["hash_algo"], attachment["hash"]) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
342 except KeyError: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
343 file_hash = None |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
344 file_sharing_elt = self.get_file_sharing_elt( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
345 [{"url": attachment["url"]}], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
346 name=attachment["name"], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
347 size=attachment["size"], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
348 file_hash=file_hash |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
349 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
350 data["xml"].addChild(file_sharing_elt) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
351 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
352 for attachment in extra_attachments: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
353 # 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
|
354 await client.sendMessage( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
355 to_jid=data['to'], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
356 message={'': ''}, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
357 subject=data['subject'], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
358 mess_type=data['type'], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
359 extra={C.MESS_KEY_ATTACHMENTS: [attachment]}, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
360 ) |
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 if ((not data['extra'] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
363 and (not data['message'] or data['message'] == {'': ''}) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
364 and not data['subject'])): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
365 # 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
|
366 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
|
367 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
368 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
|
369 # 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
|
370 # 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
|
371 # attachment |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
372 post_treat.addCallback( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
373 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
|
374 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3897
diff
changeset
|
375 return True |