annotate sat/plugins/plugin_misc_attach.py @ 3392:0957ea9137b8

plugin XEP-0047: fixed file reading and content encoding
author Goffi <goffi@goffi.org>
date Thu, 12 Nov 2020 14:53:15 +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)