# HG changeset patch # User Goffi # Date 1584882256 -3600 # Node ID 163014f09bf45fa139afd3dbdd56c036787dea59 # Parent 653fa213d2f89765e03e5d9c4b87bc46af37c6a7 plugin attach: handle large images resizing: if `C.MESS_KEY_ATTACHMENTS_RESIZE` flag is set for an attachment, it will be checked, and if it is a large image, a resized copy will be uploaded. diff -r 653fa213d2f8 -r 163014f09bf4 sat/core/constants.py --- a/sat/core/constants.py Sun Mar 22 14:01:47 2020 +0100 +++ b/sat/core/constants.py Sun Mar 22 14:04:16 2020 +0100 @@ -136,6 +136,7 @@ MESS_KEY_ATTACHMENTS = "attachments" MESS_KEY_ATTACHMENTS_MEDIA_TYPE = "media_type" MESS_KEY_ATTACHMENTS_PREVIEW = "preview" + MESS_KEY_ATTACHMENTS_RESIZE = "resize" # File encryption algorithms ENC_AES_GCM = "AES-GCM" diff -r 653fa213d2f8 -r 163014f09bf4 sat/plugins/plugin_misc_attach.py --- a/sat/plugins/plugin_misc_attach.py Sun Mar 22 14:01:47 2020 +0100 +++ b/sat/plugins/plugin_misc_attach.py Sun Mar 22 14:04:16 2020 +0100 @@ -16,15 +16,18 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from functools import partial from pathlib import Path from collections import namedtuple from twisted.internet import defer +import mimetypes +import tempfile +import shutil from sat.core.i18n import _ from sat.core import exceptions from sat.core.constants import Const as C from sat.core.log import getLogger from sat.tools import utils +from sat.tools import image log = getLogger(__name__) @@ -86,6 +89,46 @@ log.debug(f"new attachments handler: {handler}") async def attachFiles(self, client, data): + """Main method to attach file + + It will do generic pre-treatment, and call the suitable attachments handler + """ + # we check attachment for pre-treatment like large image resizing + # media_type will be added if missing (and if it can be guessed from path) + attachments = data["extra"][C.MESS_KEY_ATTACHMENTS] + tmp_dirs_to_clean = [] + for attachment in attachments: + if attachment.get(C.MESS_KEY_ATTACHMENTS_RESIZE, False): + path = Path(attachment["path"]) + try: + media_type = attachment[C.MESS_KEY_ATTACHMENTS_MEDIA_TYPE] + except KeyError: + media_type = mimetypes.guess_type(path, strict=False)[0] + if media_type is None: + log.warning( + _("Can't resize attachment of unknown type: {attachment}") + .format(attachment=attachment)) + continue + attachment[C.MESS_KEY_ATTACHMENTS_MEDIA_TYPE] = media_type + + main_type = media_type.split('/')[0] + if main_type == "image": + report = image.check(self.host, path) + if report['too_large']: + tmp_dir = Path(tempfile.mkdtemp()) + tmp_dirs_to_clean.append(tmp_dir) + new_path = tmp_dir / path.name + await image.resize( + path, report["recommended_size"], dest=new_path) + attachment["path"] = new_path + log.info( + _("Attachment {path!r} has been resized at {new_path!r}") + .format(path=str(path), new_path=str(new_path))) + else: + log.warning( + _("Can't resize attachment of type {main_type!r}: {attachment}") + .format(main_type=main_type, attachment=attachment)) + if client.encryption.isEncryptionRequested(data): handlers = self._attachments_handlers['encrypted'] else: @@ -103,6 +146,10 @@ await utils.asDeferred(handler.attach, client, data) + for dir_path in tmp_dirs_to_clean: + log.debug(f"Cleaning temporary directory at {dir_path}") + shutil.rmtree(dir_path) + return data async def uploadFiles(self, client, data, upload_cb=None): @@ -186,13 +233,13 @@ return data - def _attachFiles(self, client, data): + def _attachFiles(self, data, client): return defer.ensureDeferred(self.attachFiles(client, data)) def _sendMessageTrigger( self, client, mess_data, pre_xml_treatments, post_xml_treatments): if mess_data['extra'].get(C.MESS_KEY_ATTACHMENTS): - post_xml_treatments.addCallback(partial(self._attachFiles, client)) + post_xml_treatments.addCallback(self._attachFiles, client=client) return True async def defaultCanHandle(self, client, data): diff -r 653fa213d2f8 -r 163014f09bf4 sat/plugins/plugin_xep_0363.py --- a/sat/plugins/plugin_xep_0363.py Sun Mar 22 14:01:47 2020 +0100 +++ b/sat/plugins/plugin_xep_0363.py Sun Mar 22 14:04:16 2020 +0100 @@ -205,7 +205,7 @@ should be closed, but it is needed to send the progressFinished signal @param slot(Slot): put/get urls """ - log.info("HTTP upload finished") + log.info(f"HTTP upload finished ({slot.get})") sat_file.progressFinished({"url": slot.get}) return slot.get