Mercurial > libervia-backend
annotate sat/plugins/plugin_misc_attach.py @ 4026:fe4725bf42fb
core (memory/sqla): be sure to have a dict when serialising History.extra:
`extra` can be None, this patch avoid this value when serialising it by using an empty
dict.
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 24 Mar 2023 10:29:48 +0100 |
parents | 78b5f356900c |
children | 524856bd7b19 |
rev | line source |
---|---|
3181 | 1 #!/usr/bin/env python3 |
2 | |
3 # SàT plugin for attaching files | |
3479 | 4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
3181 | 5 |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
19 from collections import namedtuple |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
20 import mimetypes |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
21 from pathlib import Path |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
22 import shutil |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
23 import tempfile |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
24 from typing import Callable, Optional |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
25 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
26 from twisted.internet import defer |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
27 |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
28 from sat.core import exceptions |
3181 | 29 from sat.core.constants import Const as C |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
30 from sat.core.core_types import SatXMPPEntity |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
31 from sat.core.i18n import _ |
3181 | 32 from sat.core.log import getLogger |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
33 from sat.tools import utils |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
34 from sat.tools import image |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
35 |
3181 | 36 |
37 log = getLogger(__name__) | |
38 | |
39 | |
40 PLUGIN_INFO = { | |
41 C.PI_NAME: "File Attach", | |
42 C.PI_IMPORT_NAME: "ATTACH", | |
43 C.PI_TYPE: C.PLUG_TYPE_MISC, | |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
44 C.PI_MODES: C.PLUG_MODE_BOTH, |
3181 | 45 C.PI_DEPENDENCIES: ["UPLOAD"], |
46 C.PI_MAIN: "AttachPlugin", | |
47 C.PI_HANDLER: "no", | |
48 C.PI_DESCRIPTION: _("""Attachments handler"""), | |
49 } | |
50 | |
51 | |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
52 AttachmentHandler = namedtuple('AttachmentHandler', ['can_handle', 'attach', 'priority']) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
53 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
54 |
3181 | 55 class AttachPlugin: |
56 | |
57 def __init__(self, host): | |
58 log.info(_("plugin Attach initialization")) | |
59 self.host = host | |
60 self._u = host.plugins["UPLOAD"] | |
61 host.trigger.add("sendMessage", self._sendMessageTrigger) | |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
62 host.trigger.add("sendMessageComponent", self._sendMessageTrigger) |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
63 self._attachments_handlers = {'clear': [], 'encrypted': []} |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
64 self.register(self.defaultCanHandle, self.defaultAttach, False, -1000) |
3181 | 65 |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
66 def register(self, can_handle, attach, encrypted=False, priority=0): |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
67 """Register an attachments handler |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
68 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
69 @param can_handle(callable, coroutine, Deferred): a method which must return True |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
70 if this plugin can handle the upload, otherwise next ones will be tried. |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
71 This method will get client and mess_data as arguments, before the XML is |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
72 generated |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
73 @param attach(callable, coroutine, Deferred): attach the file |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
74 this method will get client and mess_data as arguments, after XML is |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
75 generated. Upload operation must be handled |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
76 hint: "UPLOAD" plugin can be used |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
77 @param encrypted(bool): True if the handler manages encrypted files |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
78 A handler can be registered twice if it handle both encrypted and clear |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
79 attachments |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
80 @param priority(int): priority of this handler, handler with higher priority will |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
81 be tried first |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
82 """ |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
83 handler = AttachmentHandler(can_handle, attach, priority) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
84 handlers = ( |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
85 self._attachments_handlers['encrypted'] |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
86 if encrypted else self._attachments_handlers['clear'] |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
87 ) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
88 if handler in handlers: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
89 raise exceptions.InternalError( |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
90 'Attachment handler has been registered twice, this should never happen' |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
91 ) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
92 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
93 handlers.append(handler) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
94 handlers.sort(key=lambda h: h.priority, reverse=True) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
95 log.debug(f"new attachments handler: {handler}") |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
96 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
97 async def attachFiles(self, client, data): |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
98 """Main method to attach file |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
99 |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
100 It will do generic pre-treatment, and call the suitable attachments handler |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
101 """ |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
102 # we check attachment for pre-treatment like large image resizing |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
103 # media_type will be added if missing (and if it can be guessed from path) |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
104 attachments = data["extra"][C.KEY_ATTACHMENTS] |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
105 tmp_dirs_to_clean = [] |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
106 for attachment in attachments: |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
107 if attachment.get(C.KEY_ATTACHMENTS_RESIZE, False): |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
108 path = Path(attachment["path"]) |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
109 try: |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
110 media_type = attachment[C.KEY_ATTACHMENTS_MEDIA_TYPE] |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
111 except KeyError: |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
112 media_type = mimetypes.guess_type(path, strict=False)[0] |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
113 if media_type is None: |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
114 log.warning( |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
115 _("Can't resize attachment of unknown type: {attachment}") |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
116 .format(attachment=attachment)) |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
117 continue |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
118 attachment[C.KEY_ATTACHMENTS_MEDIA_TYPE] = media_type |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
119 |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
120 main_type = media_type.split('/')[0] |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
121 if main_type == "image": |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
122 report = image.check(self.host, path) |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
123 if report['too_large']: |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
124 tmp_dir = Path(tempfile.mkdtemp()) |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
125 tmp_dirs_to_clean.append(tmp_dir) |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
126 new_path = tmp_dir / path.name |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
127 await image.resize( |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
128 path, report["recommended_size"], dest=new_path) |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
129 attachment["path"] = new_path |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
130 log.info( |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
131 _("Attachment {path!r} has been resized at {new_path!r}") |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
132 .format(path=str(path), new_path=str(new_path))) |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
133 else: |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
134 log.warning( |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
135 _("Can't resize attachment of type {main_type!r}: {attachment}") |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
136 .format(main_type=main_type, attachment=attachment)) |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
137 |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
138 if client.encryption.isEncryptionRequested(data): |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
139 handlers = self._attachments_handlers['encrypted'] |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
140 else: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
141 handlers = self._attachments_handlers['clear'] |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
142 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
143 for handler in handlers: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
144 can_handle = await utils.asDeferred(handler.can_handle, client, data) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
145 if can_handle: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
146 break |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
147 else: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
148 raise exceptions.NotFound( |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
149 _("No plugin can handle attachment with {destinee}").format( |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
150 destinee = data['to'] |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
151 )) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
152 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
153 await utils.asDeferred(handler.attach, client, data) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
154 |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
155 for dir_path in tmp_dirs_to_clean: |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
156 log.debug(f"Cleaning temporary directory at {dir_path}") |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
157 shutil.rmtree(dir_path) |
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
158 |
3181 | 159 return data |
160 | |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
161 async def upload_files( |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
162 self, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
163 client: SatXMPPEntity, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
164 data: dict, |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
165 upload_cb: Optional[Callable] = None |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
166 ): |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
167 """Upload file, and update attachments |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
168 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
169 invalid attachments will be removed |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
170 @param client: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
171 @param data(dict): message data |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
172 @param upload_cb(coroutine, Deferred, None): method to use for upload |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
173 if None, upload method from UPLOAD plugin will be used. |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
174 Otherwise, following kwargs will be used with the cb: |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
175 - client |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
176 - filepath |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
177 - filename |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
178 - options |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
179 the method must return a tuple similar to UPLOAD plugin's upload method, |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
180 it must contain: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
181 - progress_id |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
182 - a deferred which fire download URL |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
183 """ |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
184 if upload_cb is None: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
185 upload_cb = self._u.upload |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
186 |
3181 | 187 uploads_d = [] |
188 to_delete = [] | |
189 attachments = data["extra"]["attachments"] | |
190 | |
191 for attachment in attachments: | |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
192 if "url" in attachment and not "path" in attachment: |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
193 log.debug(f"attachment is external, we don't upload it: {attachment}") |
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
194 continue |
3181 | 195 try: |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
196 # we pop path because we don't want it to be stored, as the file can be |
3202
2e892f9f54f6
plugin attachment: remove "path" from attachment once used:
Goffi <goffi@goffi.org>
parents:
3192
diff
changeset
|
197 # only in a temporary location |
2e892f9f54f6
plugin attachment: remove "path" from attachment once used:
Goffi <goffi@goffi.org>
parents:
3192
diff
changeset
|
198 path = Path(attachment.pop("path")) |
3181 | 199 except KeyError: |
200 log.warning("no path in attachment: {attachment}") | |
201 to_delete.append(attachment) | |
202 continue | |
203 | |
204 if "url" in attachment: | |
3202
2e892f9f54f6
plugin attachment: remove "path" from attachment once used:
Goffi <goffi@goffi.org>
parents:
3192
diff
changeset
|
205 url = attachment.pop('url') |
2e892f9f54f6
plugin attachment: remove "path" from attachment once used:
Goffi <goffi@goffi.org>
parents:
3192
diff
changeset
|
206 log.warning( |
2e892f9f54f6
plugin attachment: remove "path" from attachment once used:
Goffi <goffi@goffi.org>
parents:
3192
diff
changeset
|
207 f"unexpected URL in attachment: {url!r}\nattachment: {attachment}" |
2e892f9f54f6
plugin attachment: remove "path" from attachment once used:
Goffi <goffi@goffi.org>
parents:
3192
diff
changeset
|
208 ) |
3181 | 209 |
210 try: | |
211 name = attachment["name"] | |
212 except KeyError: | |
213 name = attachment["name"] = path.name | |
214 | |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
215 attachment["size"] = path.stat().st_size |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
216 |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
217 extra = { |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
218 "attachment": attachment |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
219 } |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
220 progress_id = attachment.pop("progress_id", None) |
3182
f2bb57348587
plugin attach, XEP-0363: progress id can now be specified:
Goffi <goffi@goffi.org>
parents:
3181
diff
changeset
|
221 if progress_id: |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
222 extra["progress_id"] = progress_id |
3192
883fb4981958
plugin attach: disable TLS check if "check_certificate" is disabled
Goffi <goffi@goffi.org>
parents:
3182
diff
changeset
|
223 check_certificate = self.host.memory.getParamA( |
883fb4981958
plugin attach: disable TLS check if "check_certificate" is disabled
Goffi <goffi@goffi.org>
parents:
3182
diff
changeset
|
224 "check_certificate", "Connection", profile_key=client.profile) |
883fb4981958
plugin attach: disable TLS check if "check_certificate" is disabled
Goffi <goffi@goffi.org>
parents:
3182
diff
changeset
|
225 if not check_certificate: |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
226 extra['ignore_tls_errors'] = True |
3192
883fb4981958
plugin attach: disable TLS check if "check_certificate" is disabled
Goffi <goffi@goffi.org>
parents:
3182
diff
changeset
|
227 log.warning( |
883fb4981958
plugin attach: disable TLS check if "check_certificate" is disabled
Goffi <goffi@goffi.org>
parents:
3182
diff
changeset
|
228 _("certificate check disabled for upload, this is dangerous!")) |
3181 | 229 |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
230 __, upload_d = await upload_cb( |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
231 client=client, |
3181 | 232 filepath=path, |
233 filename=name, | |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
234 extra=extra, |
3181 | 235 ) |
236 uploads_d.append(upload_d) | |
237 | |
238 for attachment in to_delete: | |
239 attachments.remove(attachment) | |
240 | |
241 upload_results = await defer.DeferredList(uploads_d) | |
242 for idx, (success, ret) in enumerate(upload_results): | |
243 attachment = attachments[idx] | |
244 | |
245 if not success: | |
246 # ret is a failure here | |
247 log.warning(f"error while uploading {attachment}: {ret}") | |
248 continue | |
249 | |
250 attachment["url"] = ret | |
251 | |
252 return data | |
253 | |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
254 def _attachFiles(self, data, client): |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
255 return defer.ensureDeferred(self.attachFiles(client, data)) |
3181 | 256 |
257 def _sendMessageTrigger( | |
258 self, client, mess_data, pre_xml_treatments, post_xml_treatments): | |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
259 if mess_data['extra'].get(C.KEY_ATTACHMENTS): |
3223
163014f09bf4
plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
260 post_xml_treatments.addCallback(self._attachFiles, client=client) |
3181 | 261 return True |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
262 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
263 async def defaultCanHandle(self, client, data): |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
264 return True |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
265 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
266 async def defaultAttach(self, client, data): |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
267 await self.upload_files(client, data) |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
268 # TODO: handle xhtml-im |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
269 body_elt = data["xml"].body |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
270 if body_elt is None: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
271 body_elt = data["xml"].addElement("body") |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
272 attachments = data["extra"][C.KEY_ATTACHMENTS] |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
273 if attachments: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
274 body_links = '\n'.join(a['url'] for a in attachments) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
275 if str(body_elt).strip(): |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
276 # if there is already a body, we add a line feed before the first link |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
277 body_elt.addContent('\n') |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3202
diff
changeset
|
278 body_elt.addContent(body_links) |