annotate libervia/backend/plugins/plugin_misc_attach.py @ 4340:ea72364131d5 default tip @

doc (components): Update Email Gateway documentation: A section has been added to explain how attachments are handled. fix 453
author Goffi <goffi@goffi.org>
date Tue, 03 Dec 2024 00:53:18 +0100
parents 0d7bb4df2343
children
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
3479
be6d91572633 date update
Goffi <goffi@goffi.org>
parents: 3223
diff changeset
4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
3181
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
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
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
28 from libervia.backend.core import exceptions
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
29 from libervia.backend.core.constants import Const as C
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
30 from libervia.backend.core.core_types import SatXMPPEntity
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
31 from libervia.backend.core.i18n import _
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
32 from libervia.backend.core.log import getLogger
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
33 from libervia.backend.tools import utils
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
34 from libervia.backend.tools import image
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
35
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 log = getLogger(__name__)
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
39
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 PLUGIN_INFO = {
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 C.PI_NAME: "File Attach",
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 C.PI_IMPORT_NAME: "ATTACH",
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
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
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 C.PI_DEPENDENCIES: ["UPLOAD"],
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 C.PI_MAIN: "AttachPlugin",
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 C.PI_HANDLER: "no",
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 C.PI_DESCRIPTION: _("""Attachments handler"""),
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 }
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
51
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
52 AttachmentHandler = namedtuple("AttachmentHandler", ["can_handle", "attach", "priority"])
3219
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
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 class AttachPlugin:
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
56
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 def __init__(self, host):
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 log.info(_("plugin Attach initialization"))
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 self.host = host
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 self._u = host.plugins["UPLOAD"]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
61 host.trigger.add("sendMessage", self._send_message_trigger)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
62 host.trigger.add("sendMessageComponent", self._send_message_trigger)
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
63 self._attachments_handlers = {"clear": [], "encrypted": []}
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
64 self.register(self.default_can_handle, self.default_attach, False, -1000)
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
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 = (
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
85 self._attachments_handlers["encrypted"]
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
86 if encrypted
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
87 else self._attachments_handlers["clear"]
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
88 )
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
89 if handler in handlers:
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
90 raise exceptions.InternalError(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
91 "Attachment handler has been registered twice, this should never happen"
3219
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
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
94 handlers.append(handler)
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
95 handlers.sort(key=lambda h: h.priority, reverse=True)
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
96 log.debug(f"new attachments handler: {handler}")
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
97
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
98 async def attach_files(self, client, data):
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
99 """Main method to attach file
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
100
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
101 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
102 """
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
103 # 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
104 # 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
105 attachments = data["extra"][C.KEY_ATTACHMENTS]
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
106 tmp_dirs_to_clean = []
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
107 for attachment in attachments:
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
108 if attachment.get(C.KEY_ATTACHMENTS_RESIZE, False):
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
109 path = Path(attachment["path"])
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
110 try:
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
111 media_type = attachment[C.KEY_ATTACHMENTS_MEDIA_TYPE]
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
112 except KeyError:
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
113 media_type = mimetypes.guess_type(path, strict=False)[0]
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
114 if media_type is None:
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
115 log.warning(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
116 _(
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
117 "Can't resize attachment of unknown type: {attachment}"
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
118 ).format(attachment=attachment)
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
119 )
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
120 continue
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
121 attachment[C.KEY_ATTACHMENTS_MEDIA_TYPE] = media_type
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
122
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
123 main_type = media_type.split("/")[0]
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
124 if main_type == "image":
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
125 report = image.check(self.host, path)
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
126 if report["too_large"]:
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
127 tmp_dir = Path(tempfile.mkdtemp())
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
128 tmp_dirs_to_clean.append(tmp_dir)
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
129 new_path = tmp_dir / path.name
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
130 await image.resize(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
131 path, report["recommended_size"], dest=new_path
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
132 )
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
133 attachment["path"] = new_path
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
134 log.info(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
135 _(
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
136 "Attachment {path!r} has been resized at {new_path!r}"
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
137 ).format(path=str(path), new_path=str(new_path))
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
138 )
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
139 else:
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
140 log.warning(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
141 _(
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
142 "Can't resize attachment of type {main_type!r}: {attachment}"
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
143 ).format(main_type=main_type, attachment=attachment)
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
144 )
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
145
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
146 if client.encryption.is_encryption_requested(data):
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
147 handlers = self._attachments_handlers["encrypted"]
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
148 else:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
149 handlers = self._attachments_handlers["clear"]
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
150
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
151 for handler in handlers:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
152 can_handle = await utils.as_deferred(handler.can_handle, client, data)
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
153 if can_handle:
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
154 break
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
155 else:
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
156 raise exceptions.NotFound(
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
157 _("No plugin can handle attachment with {destinee}").format(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
158 destinee=data["to"]
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
159 )
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
160 )
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
161
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
162 await utils.as_deferred(handler.attach, client, data)
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
163
3223
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
164 for dir_path in tmp_dirs_to_clean:
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
165 log.debug(f"Cleaning temporary directory at {dir_path}")
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
166 shutil.rmtree(dir_path)
163014f09bf4 plugin attach: handle large images resizing:
Goffi <goffi@goffi.org>
parents: 3219
diff changeset
167
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 return data
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
169
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
170 async def upload_files(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
171 self, client: SatXMPPEntity, data: dict, upload_cb: Optional[Callable] = None
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
172 ):
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
173 """Upload file, and update attachments
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
174
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
175 invalid attachments will be removed
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
176 @param client:
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
177 @param data(dict): message data
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
178 @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
179 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
180 Otherwise, following kwargs will be used with the cb:
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
181 - client
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
182 - filepath
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
183 - filename
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
184 - options
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
185 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
186 it must contain:
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
187 - progress_id
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
188 - a deferred which fire download URL
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
189 """
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
190 if upload_cb is None:
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
191 upload_cb = self._u.upload
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
192
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 uploads_d = []
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 to_delete = []
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 attachments = data["extra"]["attachments"]
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
196
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 for attachment in attachments:
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
198 if "url" in attachment and not "path" in attachment:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
199 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
200 continue
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 try:
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
202 # 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
203 # only in a temporary location
2e892f9f54f6 plugin attachment: remove "path" from attachment once used:
Goffi <goffi@goffi.org>
parents: 3192
diff changeset
204 path = Path(attachment.pop("path"))
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 except KeyError:
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 log.warning("no path in attachment: {attachment}")
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 to_delete.append(attachment)
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 continue
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
209
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 if "url" in attachment:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
211 url = attachment.pop("url")
3202
2e892f9f54f6 plugin attachment: remove "path" from attachment once used:
Goffi <goffi@goffi.org>
parents: 3192
diff changeset
212 log.warning(
2e892f9f54f6 plugin attachment: remove "path" from attachment once used:
Goffi <goffi@goffi.org>
parents: 3192
diff changeset
213 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
214 )
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
215
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 try:
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 name = attachment["name"]
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 except KeyError:
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 name = attachment["name"] = path.name
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
220
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
221 attachment["size"] = path.stat().st_size
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
222
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
223 extra = {"attachment": attachment}
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
224 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
225 if progress_id:
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
226 extra["progress_id"] = progress_id
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
227 check_certificate = self.host.memory.param_get_a(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
228 "check_certificate", "Connection", profile_key=client.profile
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
229 )
3192
883fb4981958 plugin attach: disable TLS check if "check_certificate" is disabled
Goffi <goffi@goffi.org>
parents: 3182
diff changeset
230 if not check_certificate:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
231 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
232 log.warning(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
233 _("certificate check disabled for upload, this is dangerous!")
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
234 )
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
235
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
236 __, upload_d = await upload_cb(
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
237 client=client,
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 filepath=path,
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 filename=name,
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
240 extra=extra,
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
241 )
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 uploads_d.append(upload_d)
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
243
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
244 for attachment in to_delete:
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 attachments.remove(attachment)
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
246
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 upload_results = await defer.DeferredList(uploads_d)
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
248 for idx, (success, ret) in enumerate(upload_results):
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 attachment = attachments[idx]
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
250
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
251 if not success:
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 # ret is a failure here
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
253 log.warning(f"error while uploading {attachment}: {ret}")
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 continue
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
255
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 attachment["url"] = ret
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
257
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 return data
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
259
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
260 def _attach_files(self, data, client):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
261 return defer.ensureDeferred(self.attach_files(client, data))
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
262
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
263 def _send_message_trigger(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
264 self, client, mess_data, pre_xml_treatments, post_xml_treatments
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
265 ):
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
266 if mess_data["extra"].get(C.KEY_ATTACHMENTS):
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
267 post_xml_treatments.addCallback(self._attach_files, client=client)
3181
5ff2cf7f0aba plugin attach: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 return True
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
269
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
270 async def default_can_handle(self, client, data):
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
271 return True
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
272
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
273 async def default_attach(self, client, data):
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
274 await self.upload_files(client, data)
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
275 # TODO: handle xhtml-im
3922
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
276 body_elt = data["xml"].body
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
277 if body_elt is None:
0ff265725489 plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents: 3859
diff changeset
278 body_elt = data["xml"].addElement("body")
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3922
diff changeset
279 attachments = data["extra"][C.KEY_ATTACHMENTS]
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
280 if attachments:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
281 body_links = "\n".join(a["url"] for a in attachments)
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
282 if str(body_elt).strip():
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
283 # if there is already a body, we add a line feed before the first link
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
284 body_elt.addContent("\n")
3219
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3202
diff changeset
285 body_elt.addContent(body_links)