plugin XEP-0447: handle attachment and download:

- plugin XEP-0447 can now be used in message attachments and to retrieve an attachment
- plugin attach: `attachment` being processed is added to `extra` so the handler can inspect it
- plugin attach: `size` is added to attachment
- plugin download: a whole attachment dict is now used in `download` and
  `file_download`/`file_download_complete`. `download_uri` can be used as a shortcut when
  just a URI is used. In addition to URI scheme handler, whole attachment handlers can now
  be registered with `register_download_handler`
- plugin XEP-0363: `file_http_upload` `XEP-0363_upload_size` triggers have been renamed to
  `XEP-0363_upload_pre_slot` and is now using a dict with arguments, allowing for the size
  but also the filename to be modified, which is necessary for encryption (filename may
  be hidden from URL this way).
- plugin XEP-0446: fix wrong element name
- plugin XEP-0447: source handler can now be registered (`url-data` is registered by
  default)
- plugin XEP-0447: source parsing has been put in a separated `parse_sources_elt` method,
  as it may be useful to do it independently (notably with XEP-0448)
- plugin XEP-0447: parse received message and complete attachments when suitable
- plugin XEP-0447: can now be used with message attachments
- plugin XEP-0447: can now be used with attachments download
- renamed `options` arguments to `extra` for consistency
- some style change (progressive move from legacy camelCase to PEP8 snake_case)
- some typing

rel 379
This commit is contained in:
Goffi 2022-10-06 16:02:05 +02:00
commit a8fc70fca6

View file

@ -16,15 +16,19 @@
# 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 pathlib import Path
from collections import namedtuple
from twisted.internet import defer
import mimetypes
import tempfile
from pathlib import Path
import shutil
from sat.core.i18n import _
import tempfile
from typing import Callable, Optional
from twisted.internet import defer
from sat.core import exceptions
from sat.core.constants import Const as C
from sat.core.core_types import SatXMPPEntity
from sat.core.i18n import _
from sat.core.log import getLogger
from sat.tools import utils
from sat.tools import image
@ -37,6 +41,7 @@ PLUGIN_INFO = {
C.PI_NAME: "File Attach",
C.PI_IMPORT_NAME: "ATTACH",
C.PI_TYPE: C.PLUG_TYPE_MISC,
C.PI_MODES: C.PLUG_MODE_BOTH,
C.PI_DEPENDENCIES: ["UPLOAD"],
C.PI_MAIN: "AttachPlugin",
C.PI_HANDLER: "no",
@ -152,7 +157,12 @@ class AttachPlugin:
return data
async def uploadFiles(self, client, data, upload_cb=None):
async def upload_files(
self,
client: SatXMPPEntity,
data: dict,
upload_cb: Optional[Callable] = None
):
"""Upload file, and update attachments
invalid attachments will be removed
@ -160,7 +170,7 @@ class AttachPlugin:
@param data(dict): message data
@param upload_cb(coroutine, Deferred, None): method to use for upload
if None, upload method from UPLOAD plugin will be used.
Otherwise, following kwargs will be use with the cb:
Otherwise, following kwargs will be used with the cb:
- client
- filepath
- filename
@ -179,7 +189,7 @@ class AttachPlugin:
for attachment in attachments:
try:
# we pop path because we don't want it to be stored, as the image can be
# we pop path because we don't want it to be stored, as the file can be
# only in a temporary location
path = Path(attachment.pop("path"))
except KeyError:
@ -198,14 +208,18 @@ class AttachPlugin:
except KeyError:
name = attachment["name"] = path.name
options = {}
attachment["size"] = path.stat().st_size
extra = {
"attachment": attachment
}
progress_id = attachment.pop("progress_id", None)
if progress_id:
options["progress_id"] = progress_id
extra["progress_id"] = progress_id
check_certificate = self.host.memory.getParamA(
"check_certificate", "Connection", profile_key=client.profile)
if not check_certificate:
options['ignore_tls_errors'] = True
extra['ignore_tls_errors'] = True
log.warning(
_("certificate check disabled for upload, this is dangerous!"))
@ -213,7 +227,7 @@ class AttachPlugin:
client=client,
filepath=path,
filename=name,
options=options,
extra=extra,
)
uploads_d.append(upload_d)
@ -246,9 +260,11 @@ class AttachPlugin:
return True
async def defaultAttach(self, client, data):
await self.uploadFiles(client, data)
await self.upload_files(client, data)
# TODO: handle xhtml-im
body_elt = next(data["xml"].elements(C.NS_CLIENT, "body"))
body_elt = data["xml"].body
if body_elt is None:
body_elt = data["xml"].addElement("body")
attachments = data["extra"][C.MESS_KEY_ATTACHMENTS]
if attachments:
body_links = '\n'.join(a['url'] for a in attachments)