From 8164b496f87fc4092081151f4b92ef67d046b54a Mon Sep 17 00:00:00 2001 From: Ziad-I <68874104+Ziad-I@users.noreply.github.com> Date: Thu, 29 Aug 2024 10:50:50 +0300 Subject: [PATCH] fix #5219 underlay links are now base64 encoded in the svg before sending it to web UI this is not really the best solution and might need to look for better ones --- src/bonsai/bonsai/bim/data/webui/sioserver.py | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/bonsai/bonsai/bim/data/webui/sioserver.py b/src/bonsai/bonsai/bim/data/webui/sioserver.py index 8d88f05aa5..fe49b03bdd 100644 --- a/src/bonsai/bonsai/bim/data/webui/sioserver.py +++ b/src/bonsai/bonsai/bim/data/webui/sioserver.py @@ -1,6 +1,6 @@ import sys import os -import webbrowser + bonsai_lib_path = os.environ.get("BONSAI_LIB_PATH") bonsai_version = os.environ.get("BONSAI_VERSION") @@ -13,6 +13,8 @@ from aiohttp import web import socketio import pystache import json +import base64 +import xml.etree.ElementTree as ET sio_port = 8080 # default port @@ -56,9 +58,8 @@ class WebNamespace(socketio.AsyncNamespace): async def on_get_svg(self, sid, data): file_path = data["path"] - with open(file_path, "r") as file: - svg_data = file.read() - await sio.emit("svg_data", svg_data, room=sid, namespace="/web") + svg = await self.process_svg(file_path) + await sio.emit("svg_data", svg, room=sid, namespace="/web") async def send_cached_messages(self, sid): # Send cached messages to the connected web client @@ -70,6 +71,35 @@ class WebNamespace(socketio.AsyncNamespace): if "demo_data" in messages: await self.emit("demo_data", {"blenderId": blenderId, "data": messages["demo_data"]}, room=sid) + async def process_svg(self, file_path): + def encode_image(filepath): + # Encode file content to base64 string + with open(filepath, "rb") as file: + encoded_string = base64.b64encode(file.read()).decode("utf-8") + return f"data:image;base64,{encoded_string}" + + file_dir = os.path.dirname(file_path) + + ET.register_namespace("", "http://www.w3.org/2000/svg") + ET.register_namespace("xlink", "http://www.w3.org/1999/xlink") + + tree = ET.parse(file_path) + root = tree.getroot() + + namespaces = { + "svg": "http://www.w3.org/2000/svg", + "xlink": "http://www.w3.org/1999/xlink", + } + + for element in root.findall(".//svg:image[@xlink:href]", namespaces): + href = element.get("{http://www.w3.org/1999/xlink}href") + if href and href.endswith((".png", ".svg", ".jpeg")): + img_path = os.path.join(file_dir, href) + if os.path.exists(img_path): + base64_data = encode_image(img_path) + element.set("{http://www.w3.org/1999/xlink}href", base64_data) + return ET.tostring(root, "unicode") + # Blender namespace class BlenderNamespace(socketio.AsyncNamespace):