From b6f796775837c0ac8569f2d53b7ee9f32b217b50 Mon Sep 17 00:00:00 2001 From: axolotle Date: Fri, 17 Nov 2023 17:30:01 +0100 Subject: [PATCH] domain:config: handle "portal_logo" with "python" mode and save content in portal settings --- share/config_domain.toml | 4 ++++ src/domain.py | 41 ++++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/share/config_domain.toml b/share/config_domain.toml index 6fc5fc50a..a4b06a98c 100644 --- a/share/config_domain.toml +++ b/share/config_domain.toml @@ -5,6 +5,7 @@ i18n = "domain_config" name = "Features" [feature.portal] + # Only available for "topest" domains name = "Portal" [feature.portal.show_other_domains_apps] @@ -17,6 +18,9 @@ name = "Features" [feature.portal.portal_logo] type = "file" + accept = ["image/png", "image/jpeg", "image/svg+xml"] + mode = "python" + bind = "/usr/share/yunohost/portallogos/{filename}{ext}" [feature.portal.portal_theme] type = "select" diff --git a/src/domain.py b/src/domain.py index 75fd57a6c..71f5864f5 100644 --- a/src/domain.py +++ b/src/domain.py @@ -762,26 +762,6 @@ class DomainConfigPanel(ConfigPanel): "portal_theme", ] - if "portal_logo" in next_settings: - - import magic, hashlib - with open(next_settings["portal_logo"], "rb") as f: - file_content = f.read() - mimetype = magic.Magic(mime=True).from_buffer(file_content) - if mimetype not in ["image/png", "image/jpeg"]: - raise YunohostValidationError(f"Unsupported image type : {mimetype}", raw=True) - ext = mimetype.split("/")[-1] - m = hashlib.sha256() - m.update(file_content) - sha256sum = m.hexdigest() - filename = f"/usr/share/yunohost/portallogos/{sha256sum}.{ext}" - with open(filename, "wb") as f: - f.write(file_content) - next_settings["portal_logo"] = filename - # FIXME : the previous line doesn't actually set anything in the actual form ... - # ... and calling `form.portal_logo = filename` would actually make it sort of "re-upload" the file to another place ... - # not sure how to address this issue ... - if _get_parent_domain_of(self.entity, topest=True) is None and any( option in next_settings for option in portal_options ): @@ -793,6 +773,27 @@ class DomainConfigPanel(ConfigPanel): portal_values = form.dict(include=set(portal_options)) + if "portal_logo" in next_settings: + if previous_settings.get("portal_logo"): + try: + os.remove(previous_settings["portal_logo"]) + except: + logger.warning( + f"Coulnd't remove previous logo file, maybe the file was already deleted, path: {previous_settings['portal_logo']}" + ) + + if next_settings["portal_logo"]: + # Save the file content as `{mimetype}:{base64content}` in portal settings + # while keeping the file path in the domain settings + from base64 import b64encode + from magic import Magic + + file_content = Path(portal_values["portal_logo"]).read_bytes() + mimetype = Magic(mime=True).from_buffer(file_content) + portal_values["portal_logo"] = ( + mimetype + ":" + b64encode(file_content).decode("utf-8") + ) + portal_settings_path = Path(f"{PORTAL_SETTINGS_DIR}/{self.entity}.json") portal_settings: dict[str, Any] = {"apps": {}}