annotate sat/plugins/plugin_misc_attach.py @ 3231:e756e0eb1be4

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