Mercurial > libervia-backend
annotate libervia/backend/plugins/plugin_misc_download.py @ 4309:b56b1eae7994
component email gateway: add multicasting:
XEP-0033 multicasting is now supported both for incoming and outgoing messages. XEP-0033
metadata are converted to suitable Email headers and vice versa.
Email address and JID are both supported, and delivery is done by the gateway when
suitable on incoming messages.
rel 450
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 26 Sep 2024 16:12:01 +0200 |
parents | 0d7bb4df2343 |
children |
rev | line source |
---|---|
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1 #!/usr/bin/env python3 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
2 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
3 # SAT plugin for downloading files |
3479 | 4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
5 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
6 # This program is free software: you can redistribute it and/or modify |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
7 # it under the terms of the GNU Affero General Public License as published by |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
8 # the Free Software Foundation, either version 3 of the License, or |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
9 # (at your option) any later version. |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
10 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
11 # This program is distributed in the hope that it will be useful, |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
14 # GNU Affero General Public License for more details. |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
15 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
16 # You should have received a copy of the GNU Affero General Public License |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
18 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
19 import hashlib |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
20 from pathlib import Path |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
21 from typing import Any, Dict, Optional, Union, Tuple, Callable |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
22 from urllib.parse import unquote, urlparse |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
23 |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
24 import treq |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
25 from twisted.internet import defer |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
26 from twisted.words.protocols.jabber import error as jabber_error |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
27 |
4071
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
28 from libervia.backend.core import exceptions |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
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:
4037
diff
changeset
|
30 from libervia.backend.core.core_types import SatXMPPEntity |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
31 from libervia.backend.core.i18n import D_, _ |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
32 from libervia.backend.core.log import getLogger |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
33 from libervia.backend.tools import xml_tools |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
34 from libervia.backend.tools import stream |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
35 from libervia.backend.tools.common import data_format |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
36 from libervia.backend.tools.web import treq_client_no_ssl |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
37 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
38 log = getLogger(__name__) |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
39 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
40 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
41 PLUGIN_INFO = { |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
42 C.PI_NAME: "File Download", |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
43 C.PI_IMPORT_NAME: "DOWNLOAD", |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
44 C.PI_TYPE: C.PLUG_TYPE_MISC, |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
45 C.PI_MODES: C.PLUG_MODE_BOTH, |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
46 C.PI_MAIN: "DownloadPlugin", |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
47 C.PI_HANDLER: "no", |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
48 C.PI_DESCRIPTION: _("""File download management"""), |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
49 } |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
50 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
51 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
52 class DownloadPlugin(object): |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
53 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
54 def __init__(self, host): |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
55 log.info(_("plugin Download initialization")) |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
56 self.host = host |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
57 host.bridge.add_method( |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
58 "file_download", |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
59 ".plugin", |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
60 in_sign="ssss", |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
61 out_sign="s", |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
62 method=self._file_download, |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
63 async_=True, |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
64 ) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
65 host.bridge.add_method( |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
66 "file_download_complete", |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
67 ".plugin", |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
68 in_sign="ssss", |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
69 out_sign="s", |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
70 method=self._file_download_complete, |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
71 async_=True, |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
72 ) |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
73 self._download_callbacks = {} |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
74 self._scheme_callbacks = {} |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
75 self.register_scheme("http", self.download_http) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
76 self.register_scheme("https", self.download_http) |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
77 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
78 def _file_download( |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
79 self, attachment_s: str, dest_path: str, extra_s: str, profile: str |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
80 ) -> defer.Deferred: |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
81 d = defer.ensureDeferred( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
82 self.file_download( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
83 self.host.get_client(profile), |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
84 data_format.deserialise(attachment_s), |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
85 Path(dest_path), |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
86 data_format.deserialise(extra_s), |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
87 ) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
88 ) |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
89 d.addCallback(lambda ret: data_format.serialise(ret)) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
90 return d |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
91 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
92 async def file_download( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
93 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
94 client: SatXMPPEntity, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
95 attachment: Dict[str, Any], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
96 dest_path: Path, |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
97 extra: Optional[Dict[str, Any]] = None, |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
98 ) -> Dict[str, Any]: |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
99 """Download a file using best available method |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
100 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
101 parameters are the same as for [download] |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
102 @return (dict): action dictionary, with progress id in case of success, else xmlui |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
103 message |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
104 """ |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
105 try: |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
106 progress_id, __ = await self.download(client, attachment, dest_path, extra) |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
107 except Exception as e: |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
108 if ( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
109 isinstance(e, jabber_error.StanzaError) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
110 and e.condition == "not-acceptable" |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
111 ): |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
112 reason = e.text |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
113 else: |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
114 reason = str(e) |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
115 msg = D_("Can't download file: {reason}").format(reason=reason) |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
116 log.warning(msg) |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
117 return { |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
118 "xmlui": xml_tools.note( |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
119 msg, D_("Can't download file"), C.XMLUI_DATA_LVL_WARNING |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
120 ).toXml() |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
121 } |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
122 else: |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
123 return {"progress": progress_id} |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
124 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
125 def _file_download_complete( |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
126 self, attachment_s: str, dest_path: str, extra_s: str, profile: str |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
127 ) -> defer.Deferred: |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
128 d = defer.ensureDeferred( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
129 self.file_download_complete( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
130 self.host.get_client(profile), |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
131 data_format.deserialise(attachment_s), |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
132 Path(dest_path), |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
133 data_format.deserialise(extra_s), |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
134 ) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
135 ) |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
136 d.addCallback(lambda path: str(path)) |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
137 return d |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
138 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
139 async def file_download_complete( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
140 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
141 client: SatXMPPEntity, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
142 attachment: Dict[str, Any], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
143 dest_path: Path, |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
144 extra: Optional[Dict[str, Any]] = None, |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
145 ) -> str: |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
146 """Helper method to fully download a file and return its path |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
147 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
148 parameters are the same as for [download] |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
149 @return (str): path to the downloaded file |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
150 use empty string to store the file in cache |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
151 """ |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
152 __, download_d = await self.download(client, attachment, dest_path, extra) |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
153 dest_path = await download_d |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
154 return dest_path |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
155 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
156 async def download_uri( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
157 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
158 client: SatXMPPEntity, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
159 uri: str, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
160 dest_path: Union[Path, str], |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
161 extra: Optional[Dict[str, Any]] = None, |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
162 ) -> Tuple[str, defer.Deferred]: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
163 if extra is None: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
164 extra = {} |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
165 uri_parsed = urlparse(uri, "http") |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
166 if dest_path: |
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
167 dest_path = Path(dest_path) |
3211
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
168 cache_uid = None |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
169 else: |
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
170 filename = Path(unquote(uri_parsed.path)).name.strip() or C.FILE_DEFAULT_NAME |
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
171 # we don't use Path.suffixes because we don't want to have more than 2 |
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
172 # suffixes, but we still want to handle suffixes like "tar.gz". |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
173 stem, *suffixes = filename.rsplit(".", 2) |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
174 # we hash the URL to have an unique identifier, and avoid double download |
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
175 url_hash = hashlib.sha256(uri_parsed.geturl().encode()).hexdigest() |
3211
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
176 cache_uid = f"{stem}_{url_hash}" |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
177 cache_data = client.cache.get_metadata(cache_uid) |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
178 if cache_data is not None: |
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
179 # file is already in cache, we return it |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
180 download_d = defer.succeed(cache_data["path"]) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
181 return "", download_d |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
182 else: |
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
183 # the file is not in cache |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
184 unique_name = ".".join([cache_uid] + suffixes) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
185 with client.cache.cache_data( |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
186 "DOWNLOAD", cache_uid, filename=unique_name |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
187 ) as f: |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
188 # we close the file and only use its name, the file will be opened |
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
189 # by the registered callback |
3211
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
190 dest_path = Path(f.name) |
3205
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3187
diff
changeset
|
191 |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3187
diff
changeset
|
192 # should we check certificates? |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
193 check_certificate = self.host.memory.param_get_a( |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
194 "check_certificate", "Connection", profile_key=client.profile |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
195 ) |
3205
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3187
diff
changeset
|
196 if not check_certificate: |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
197 extra["ignore_tls_errors"] = True |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
198 log.warning(_("certificate check disabled for download, this is dangerous!")) |
3205
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3187
diff
changeset
|
199 |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
200 try: |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
201 callback = self._scheme_callbacks[uri_parsed.scheme] |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
202 except KeyError: |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
203 raise exceptions.NotFound(f"Can't find any handler for uri {uri}") |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
204 else: |
3211
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
205 try: |
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
206 progress_id, download_d = await callback( |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
207 client, uri_parsed, dest_path, extra |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
208 ) |
3211
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
209 except Exception as e: |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
210 log.warning( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
211 _("Can't download URI {uri}: {reason}").format(uri=uri, reason=e) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
212 ) |
3211
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
213 if cache_uid is not None: |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
214 client.cache.remove_from_cache(cache_uid) |
3211
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
215 elif dest_path.exists(): |
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
216 dest_path.unlink() |
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
217 raise e |
3187
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
218 download_d.addCallback(lambda __: dest_path) |
d92a144f3589
plugin download: use cache if dest_path is empty:
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
219 return progress_id, download_d |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
220 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
221 async def download( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
222 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
223 client: SatXMPPEntity, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
224 attachment: Dict[str, Any], |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
225 dest_path: Union[Path, str], |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
226 extra: Optional[Dict[str, Any]] = None, |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
227 ) -> Tuple[str, defer.Deferred]: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
228 """Download a file from URI using suitable method |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
229 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
230 @param uri: URI to the file to download |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
231 @param dest_path: where the file must be downloaded |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
232 if empty string, the file will be stored in local path |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
233 @param extra: options depending on scheme handler |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
234 Some common options: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
235 - ignore_tls_errors(bool): True to ignore SSL/TLS certificate verification |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
236 used only if HTTPS transport is needed |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
237 @return: ``progress_id`` and a Deferred which fire download URL when download is |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
238 finished. |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
239 ``progress_id`` can be empty string if the file already exist and is not |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
240 downloaded again (can happen if cache is used with empty ``dest_path``). |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
241 """ |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
242 uri = attachment.get("uri") |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
243 if uri: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
244 return await self.download_uri(client, uri, dest_path, extra) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
245 else: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
246 for source in attachment.get("sources", []): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
247 source_type = source.get("type") |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
248 if not source_type: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
249 log.warning( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
250 "source type is missing for source: {source}\nattachment: " |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
251 f"{attachment}" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
252 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
253 continue |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
254 try: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
255 cb = self._download_callbacks[source_type] |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
256 except KeyError: |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
257 log.warning(f"no source handler registered for {source_type!r}") |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
258 else: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
259 try: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
260 return await cb(client, attachment, source, dest_path, extra) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
261 except exceptions.CancelError as e: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
262 # the handler can't or doesn't want to handle this source |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
263 log.debug( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
264 f"Following source handling by {cb} has been cancelled ({e}):" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
265 f"{source}" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
266 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
267 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
268 log.warning( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
269 "no source could be handled, we can't download the attachment:\n" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
270 f"{attachment}" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
271 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
272 raise exceptions.FeatureNotFound("no handler could manage the attachment") |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
273 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
274 def register_download_handler( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
275 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
276 source_type: str, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
277 callback: Callable[ |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
278 [ |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
279 SatXMPPEntity, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
280 Dict[str, Any], |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
281 Dict[str, Any], |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
282 Union[str, Path], |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
283 Dict[str, Any], |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
284 ], |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
285 Tuple[str, defer.Deferred], |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
286 ], |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
287 ) -> None: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
288 """Register a handler to manage a type of attachment source |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
289 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
290 @param source_type: ``type`` of source handled |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
291 This is usually the namespace of the protocol used |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
292 @param callback: method to call to manage the source. |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
293 Call arguments are the same as for [download], with an extra ``source`` dict |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
294 which is used just after ``attachment`` to give a quick reference to the |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
295 source used. |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
296 The callabke must return a tuple with: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
297 - progress ID |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
298 - a Deferred which fire whant the file is fully downloaded |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
299 """ |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
300 if source_type is self._download_callbacks: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
301 raise exceptions.ConflictError( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
302 f"The is already a callback registered for source type {source_type!r}" |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
303 ) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
304 self._download_callbacks[source_type] = callback |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
305 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
306 def register_scheme(self, scheme: str, download_cb: Callable) -> None: |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
307 """Register an URI scheme handler |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
308 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
309 @param scheme: URI scheme this callback is handling |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
310 @param download_cb: callback to download a file |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
311 arguments are: |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
312 - (SatXMPPClient) client |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
313 - (urllib.parse.SplitResult) parsed URI |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
314 - (Path) destination path where the file must be downloaded |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
315 - (dict) options |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
316 must return a tuple with progress_id and a Deferred which fire when download |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
317 is finished |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
318 """ |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
319 if scheme in self._scheme_callbacks: |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
320 raise exceptions.ConflictError( |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
321 f"A method with scheme {scheme!r} is already registered" |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
322 ) |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
323 self._scheme_callbacks[scheme] = download_cb |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
324 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
325 def unregister(self, scheme): |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
326 try: |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
327 del self._scheme_callbacks[scheme] |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
328 except KeyError: |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
329 raise exceptions.NotFound(f"No callback registered for scheme {scheme!r}") |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
330 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
331 def errback_download(self, file_obj, download_d, resp): |
3186
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
332 """Set file_obj and download deferred appropriatly after a network error |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
333 |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
334 @param file_obj(SatFile): file where the download must be done |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
335 @param download_d(Deferred): deffered which must be fired on complete download |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
336 @param resp(treq.response.IResponse): treq response |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
337 """ |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
338 msg = f"HTTP error ({resp.code}): {resp.phrase.decode()}" |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
339 file_obj.close(error=msg) |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
340 download_d.errback(exceptions.NetworkError(msg)) |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
341 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
342 async def download_http(self, client, uri_parsed, dest_path, options): |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
343 url = uri_parsed.geturl() |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
344 |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
345 if options.get("ignore_tls_errors", False): |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
346 log.warning("TLS certificate check disabled, this is highly insecure") |
3205
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3187
diff
changeset
|
347 treq_client = treq_client_no_ssl |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3187
diff
changeset
|
348 else: |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3187
diff
changeset
|
349 treq_client = treq |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3187
diff
changeset
|
350 |
3211
4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
351 head_data = await treq_client.head(url) |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
352 try: |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
353 content_length = int(head_data.headers.getRawHeaders("content-length")[0]) |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
354 except (KeyError, TypeError, IndexError): |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
355 content_length = None |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
356 log.debug(f"No content lenght found at {url}") |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
357 file_obj = stream.SatFile( |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
358 self.host, |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
359 client, |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
360 dest_path, |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
361 mode="wb", |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
362 size=content_length, |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
363 ) |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
364 |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
365 progress_id = file_obj.uid |
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
366 |
3205
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3187
diff
changeset
|
367 resp = await treq_client.get(url, unbuffered=True) |
3186
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
368 if resp.code == 200: |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
369 d = treq.collect(resp, file_obj.write) |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
370 d.addBoth(lambda _: file_obj.close()) |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
371 else: |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
372 d = defer.Deferred() |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
373 self.errback_download(file_obj, d, resp) |
3088
d1464548055a
plugin file download: meta plugin to handle file download:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
374 return progress_id, d |