Mercurial > libervia-backend
changeset 3201:439e2f88c3a9
core, bridge: new `imageGeneratePreview` helped method to generate a thumbnail
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 01 Mar 2020 18:48:06 +0100 |
parents | 5c3bf37f2202 |
children | 2e892f9f54f6 |
files | sat/bridge/bridge_constructor/bridge_template.ini sat/bridge/dbus_bridge.py sat/core/constants.py sat/core/sat_main.py sat_frontends/bridge/dbus_bridge.py sat_frontends/bridge/pb.py |
diffstat | 6 files changed, 90 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/sat/bridge/bridge_constructor/bridge_template.ini Sun Mar 01 18:47:05 2020 +0100 +++ b/sat/bridge/bridge_constructor/bridge_template.ini Sun Mar 01 18:48:06 2020 +0100 @@ -972,3 +972,14 @@ doc_param_2=height: height of the new image doc_return=path of the new image with desired size the image must be deleted once not needed anymore + +[imageGeneratePreview] +async= +type=method +category=core +sig_in=ss +sig_out=s +doc=Generate a preview of an image in cache +doc_param_0=image_path: path of the original image +doc_param_1=%(doc_profile_key)s +doc_return=path to the preview in cache
--- a/sat/bridge/dbus_bridge.py Sun Mar 01 18:47:05 2020 +0100 +++ b/sat/bridge/dbus_bridge.py Sun Mar 01 18:48:06 2020 +0100 @@ -397,6 +397,12 @@ return self._callback("imageCheck", str(arg_0)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, + in_signature='ss', out_signature='s', + async_callbacks=('callback', 'errback')) + def imageGeneratePreview(self, image_path, profile_key, callback=None, errback=None): + return self._callback("imageGeneratePreview", str(image_path), str(profile_key), callback=callback, errback=errback) + + @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='sii', out_signature='s', async_callbacks=('callback', 'errback')) def imageResize(self, image_path, width, height, callback=None, errback=None):
--- a/sat/core/constants.py Sun Mar 01 18:47:05 2020 +0100 +++ b/sat/core/constants.py Sun Mar 01 18:48:06 2020 +0100 @@ -135,6 +135,7 @@ MESS_KEY_ATTACHMENTS = "attachments" MESS_KEY_ATTACHMENTS_MEDIA_TYPE = "media_type" + MESS_KEY_ATTACHMENTS_PREVIEW = "preview" # File encryption algorithms ENC_AES_GCM = "AES-GCM"
--- a/sat/core/sat_main.py Sun Mar 01 18:47:05 2020 +0100 +++ b/sat/core/sat_main.py Sun Mar 01 18:48:06 2020 +0100 @@ -20,6 +20,8 @@ import sys import os.path import uuid +import hashlib +from pathlib import Path import sat from sat.core.i18n import _, D_, languageSwitch from sat.core import patches @@ -173,6 +175,7 @@ self.bridge.register_method("namespacesGet", self.getNamespaces) self.bridge.register_method("imageCheck", self._imageCheck) self.bridge.register_method("imageResize", self._imageResize) + self.bridge.register_method("imageGeneratePreview", self._imageGeneratePreview) self.memory.initialized.addCallback(lambda __: defer.ensureDeferred(self._postMemoryInit())) @@ -684,6 +687,45 @@ d.addCallback(lambda new_image_path: str(new_image_path)) return d + def _imageGeneratePreview(self, path, profile_key): + client = self.getClient(profile_key) + d = defer.ensureDeferred(self.imageGeneratePreview(client, Path(path))) + d.addCallback(lambda preview_path: str(preview_path)) + return d + + async def imageGeneratePreview(self, client, path): + """Helper method to generate in cache a preview of an image + + @param path(Path): path to the image + @return (Path): path to the generated preview + """ + report = images.checkImage(self, path, max_size=(300, 300)) + + if not report['too_large']: + # in the unlikely case that image is already smaller than a preview + preview_path = path + else: + # we use hash as id, to re-use potentially existing preview + path_hash = hashlib.sha256(str(path).encode()).hexdigest() + uid = f"{path.stem}_{path_hash}_preview" + filename = f"{uid}{path.suffix.lower()}" + metadata = client.cache.getMetadata(uid=uid) + if metadata is not None: + preview_path = metadata['path'] + else: + with client.cache.cacheData( + source='HOST_PREVIEW', + uid=uid, + filename=filename) as cache_f: + + preview_path = await images.resizeImage( + path, + new_size=report['recommended_size'], + dest=cache_f + ) + + return preview_path + # local dirs def getLocalPath(self, client, dir_name, *extra_path, **kwargs):
--- a/sat_frontends/bridge/dbus_bridge.py Sun Mar 01 18:47:05 2020 +0100 +++ b/sat_frontends/bridge/dbus_bridge.py Sun Mar 01 18:48:06 2020 +0100 @@ -489,6 +489,15 @@ kwargs['error_handler'] = error_handler return str(self.db_core_iface.imageCheck(arg_0, **kwargs)) + def imageGeneratePreview(self, image_path, profile_key, callback=None, errback=None): + if callback is None: + error_handler = None + else: + if errback is None: + errback = log.error + error_handler = lambda err:errback(dbus_to_bridge_exception(err)) + return str(self.db_core_iface.imageGeneratePreview(image_path, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)) + def imageResize(self, image_path, width, height, callback=None, errback=None): if callback is None: error_handler = None @@ -1149,6 +1158,14 @@ self.db_core_iface.imageCheck(arg_0, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler) return fut + def imageGeneratePreview(self, image_path, profile_key): + loop = asyncio.get_running_loop() + fut = loop.create_future() + reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret) + error_handler = lambda err: loop.call_soon_threadsafe(fut.set_exception, dbus_to_bridge_exception(err)) + self.db_core_iface.imageGeneratePreview(image_path, profile_key, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler) + return fut + def imageResize(self, image_path, width, height): loop = asyncio.get_running_loop() fut = loop.create_future()
--- a/sat_frontends/bridge/pb.py Sun Mar 01 18:47:05 2020 +0100 +++ b/sat_frontends/bridge/pb.py Sun Mar 01 18:48:06 2020 +0100 @@ -383,6 +383,14 @@ errback = self._generic_errback d.addErrback(errback) + def imageGeneratePreview(self, image_path, profile_key, callback=None, errback=None): + d = self.root.callRemote("imageGeneratePreview", image_path, profile_key) + if callback is not None: + d.addCallback(callback) + if errback is None: + errback = self._generic_errback + d.addErrback(errback) + def imageResize(self, image_path, width, height, callback=None, errback=None): d = self.root.callRemote("imageResize", image_path, width, height) if callback is not None: @@ -818,6 +826,11 @@ d.addErrback(self._errback) return d.asFuture(asyncio.get_event_loop()) + def imageGeneratePreview(self, image_path, profile_key): + d = self.root.callRemote("imageGeneratePreview", image_path, profile_key) + d.addErrback(self._errback) + return d.asFuture(asyncio.get_event_loop()) + def imageResize(self, image_path, width, height): d = self.root.callRemote("imageResize", image_path, width, height) d.addErrback(self._errback)