Mercurial > libervia-backend
view sat/plugins/plugin_misc_attach.py @ 3182:f2bb57348587
plugin attach, XEP-0363: progress id can now be specified:
progress id can be specified in options, using the "progress_id" option, this can be
more handy for frontends to keep track of attachments progresses.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 23 Feb 2020 17:48:26 +0100 |
parents | 5ff2cf7f0aba |
children | 883fb4981958 |
line wrap: on
line source
#!/usr/bin/env python3 # SàT plugin for attaching files # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from functools import partial from pathlib import Path from twisted.internet import defer from sat.core.i18n import _ from sat.core.constants import Const as C from sat.core.log import getLogger log = getLogger(__name__) PLUGIN_INFO = { C.PI_NAME: "File Attach", C.PI_IMPORT_NAME: "ATTACH", C.PI_TYPE: C.PLUG_TYPE_MISC, C.PI_DEPENDENCIES: ["UPLOAD"], C.PI_MAIN: "AttachPlugin", C.PI_HANDLER: "no", C.PI_DESCRIPTION: _("""Attachments handler"""), } class AttachPlugin: def __init__(self, host): log.info(_("plugin Attach initialization")) self.host = host self._u = host.plugins["UPLOAD"] host.trigger.add("sendMessage", self._sendMessageTrigger) def _attachFiles(self, client, data): # TODO: handle xhtml-im body_elt = next(data["xml"].elements((C.NS_CLIENT, "body"))) for attachment in data["extra"][C.MESS_KEY_ATTACHMENTS]: body_elt.addContent(f'\n{attachment["url"]}') return data async def uploadFiles(self, client, data): uploads_d = [] to_delete = [] attachments = data["extra"]["attachments"] for attachment in attachments: try: path = Path(attachment["path"]) except KeyError: log.warning("no path in attachment: {attachment}") to_delete.append(attachment) continue if "url" in attachment: log.warning("invalid attachment: unknown URL") to_delete.append(attachment) try: name = attachment["name"] except KeyError: name = attachment["name"] = path.name options = {} progress_id = attachment.get("progress_id") if progress_id: options["progress_id"] = attachment["progress_id"] if client.encryption.isEncryptionRequested(data): # FIXME: we should not use implementation specific value here # but for not it's the only file encryption method available with # with upload. options['encryption'] = C.ENC_AES_GCM __, upload_d = await self._u.upload( client, filepath=path, filename=name, options=options, ) uploads_d.append(upload_d) for attachment in to_delete: attachments.remove(attachment) upload_results = await defer.DeferredList(uploads_d) for idx, (success, ret) in enumerate(upload_results): attachment = attachments[idx] if not success: # ret is a failure here log.warning(f"error while uploading {attachment}: {ret}") continue attachment["url"] = ret return data def _uploadFiles(self, client, data): return defer.ensureDeferred(self.uploadFiles(client, data)) def _sendMessageTrigger( self, client, mess_data, pre_xml_treatments, post_xml_treatments): if mess_data['extra'].get(C.MESS_KEY_ATTACHMENTS): pre_xml_treatments.addCallback(partial(self._uploadFiles, client)) post_xml_treatments.addCallback(partial(self._attachFiles, client)) return True