From a76ab59543cfb95588c0298050265a6d7478093b Mon Sep 17 00:00:00 2001 From: Herwin Bozet Date: Wed, 26 Feb 2025 21:24:16 +0100 Subject: [PATCH] Implemented conditionally included applet resource for standalone mode Update excel-password-remover.yml, png-chunk-analyser.yml, and 6 more files... --- data/applets/excel-password-remover.yml | 7 +- data/applets/png-chunk-analyser.yml | 5 +- data/applets/png-optimizer.yml | 5 +- data/applets/uuid-generator.yml | 5 +- data/applets/web-usb-test.yml | 5 +- .../excel-password-remover.mjs | 1 - website/content/dataclasses.py | 56 ++++++++++++- website/renderers/applet.py | 81 +++++++++++++++---- 8 files changed, 131 insertions(+), 34 deletions(-) diff --git a/data/applets/excel-password-remover.yml b/data/applets/excel-password-remover.yml index 730ecd7..8b84470 100644 --- a/data/applets/excel-password-remover.yml +++ b/data/applets/excel-password-remover.yml @@ -1,8 +1,9 @@ - applets: - id: "excel-password-remover" resources: scripts: - - "excel-password-remover.mjs" + - "https://cdn.nibblepoker.lu/JSZip/v3.10.1/jszip.min.js" + - "standalone://jszip.min.js" + - "applet://excel-password-remover.mjs" stylesheets: - - "excel-password-remover.css" + - "applet://excel-password-remover.css" diff --git a/data/applets/png-chunk-analyser.yml b/data/applets/png-chunk-analyser.yml index 0a86b17..6384dff 100644 --- a/data/applets/png-chunk-analyser.yml +++ b/data/applets/png-chunk-analyser.yml @@ -1,8 +1,7 @@ - applets: - id: "png-chunk-analyser" resources: scripts: - - "png-chunk-analyser.mjs" + - "applet://png-chunk-analyser.mjs" stylesheets: - - "png-chunk-analyser.css" + - "applet://png-chunk-analyser.css" diff --git a/data/applets/png-optimizer.yml b/data/applets/png-optimizer.yml index 68c4fe2..a1b536e 100644 --- a/data/applets/png-optimizer.yml +++ b/data/applets/png-optimizer.yml @@ -1,8 +1,7 @@ - applets: - id: "png-optimizer" resources: scripts: - - "png-optimizer.mjs" + - "applet://png-optimizer.mjs" stylesheets: - - "png-optimizer.css" + - "applet://png-optimizer.css" diff --git a/data/applets/uuid-generator.yml b/data/applets/uuid-generator.yml index f88240c..dd15406 100644 --- a/data/applets/uuid-generator.yml +++ b/data/applets/uuid-generator.yml @@ -1,8 +1,7 @@ - applets: - id: "web-usb-test" resources: scripts: - - "web-usb-test.mjs" + - "applet://web-usb-test.mjs" stylesheets: - - "web-usb-test.css" + - "applet://web-usb-test.css" diff --git a/data/applets/web-usb-test.yml b/data/applets/web-usb-test.yml index 49d0333..9e256f3 100644 --- a/data/applets/web-usb-test.yml +++ b/data/applets/web-usb-test.yml @@ -1,8 +1,7 @@ - applets: - id: "uuid-generator" resources: scripts: - - "uuid-generator.mjs" + - "applet://uuid-generator.mjs" stylesheets: - - "uuid-generator.css" + - "applet://uuid-generator.css" diff --git a/static/resources/NibblePoker/applets/excel-password-remover/excel-password-remover.mjs b/static/resources/NibblePoker/applets/excel-password-remover/excel-password-remover.mjs index 80bd0b9..2bc5832 100644 --- a/static/resources/NibblePoker/applets/excel-password-remover/excel-password-remover.mjs +++ b/static/resources/NibblePoker/applets/excel-password-remover/excel-password-remover.mjs @@ -1,4 +1,3 @@ - const excelFileRegex = /^.*\.xls[xm]$/gi; const excelWorksheetRegex = /^xl\/worksheets\/.*.xml$/gi; diff --git a/website/content/dataclasses.py b/website/content/dataclasses.py index 7dbc1ad..fe53b17 100644 --- a/website/content/dataclasses.py +++ b/website/content/dataclasses.py @@ -1,5 +1,7 @@ from dataclasses import dataclass, field +from enum import Enum from typing import Optional +from urllib.parse import ParseResult, urlparse from locked_dict.locked_dict import LockedDict @@ -70,10 +72,59 @@ class ContentMetadata: self.general = ContentGeneralMetadata(**self.general) +class ContentResourceType(Enum): + UNKNOWN = [] + REMOTE = ["http", "https"] + APPLET = ["applet"] + STANDALONE = ["standalone", "stand"] + + +class ContentResourceDefinition: + raw_uri: str + resource_type: ContentResourceType + resource_uri: ParseResult + + def __init__(self, raw_uri): + self.raw_uri = raw_uri + self.resource_uri = urlparse(self.raw_uri) + + self.resource_type = ContentResourceType.UNKNOWN + for content_resource_type in ContentResourceType: + if self.resource_uri.scheme in content_resource_type.value: + self.resource_type = content_resource_type + + def can_be_standalone(self): + return self.resource_type in [ContentResourceType.STANDALONE, ContentResourceType.APPLET] + + def is_standalone(self): + return self.resource_type == ContentResourceType.STANDALONE + + def is_remote(self): + return self.resource_type == ContentResourceType.REMOTE + + def is_applet(self): + return self.resource_type == ContentResourceType.APPLET + + def get_clean_path(self): + return self.raw_uri.replace(f"{self.resource_uri.scheme}://", "") + + def __repr__(self): + return (f"ContentResourceDefinition(raw_uri: {self.raw_uri}, " + f"resource_type: {self.resource_type}, " + f"resource_uri: {self.resource_uri})") + + @dataclass class ContentResource: - scripts: list[str] = field(default_factory=list) - stylesheets: list[str] = field(default_factory=list) + scripts: list[ContentResourceDefinition] = field(default_factory=list) + stylesheets: list[ContentResourceDefinition] = field(default_factory=list) + + def __post_init__(self): + self.scripts: list[str] + self.stylesheets: list[str] + + self.scripts = [ContentResourceDefinition(x) for x in self.scripts] + self.stylesheets = [ContentResourceDefinition(x) for x in self.stylesheets] @dataclass @@ -84,6 +135,7 @@ class ContentApplet: def __post_init__(self): self.resources: dict self.resources = ContentResource(**self.resources) + # print(self.resources) @dataclass diff --git a/website/renderers/applet.py b/website/renderers/applet.py index bc9a32f..18bc190 100644 --- a/website/renderers/applet.py +++ b/website/renderers/applet.py @@ -9,15 +9,39 @@ def render_applet_head(applet_data: ContentApplet, is_standalone: bool = False) applet_style_html = "" for applet_style in applet_data.resources.stylesheets: + rsc_path = None + if is_standalone: - with open(os.path.join("./static/resources/NibblePoker/applets/", applet_data.id, applet_style)) as applet_style_file: - applet_style_html += "" + if not applet_style.can_be_standalone(): + continue + + if applet_style.is_applet(): + rsc_path = os.path.join( + "./static/resources/NibblePoker/applets/", + applet_data.id, + applet_style.get_clean_path()) + print(applet_style) + elif applet_style.is_standalone(): + rsc_path = os.path.join( + "./static/resources/Standalone/", + applet_style.get_clean_path()) + + if rsc_path is not None: + with open(rsc_path) as applet_style_file: + applet_style_html += "" + else: - applet_style_html += ("") + if applet_style.is_applet(): + rsc_path = url_for( + "static", + filename="/resources/NibblePoker/applets/" + + applet_data.id + "/" + + applet_style.get_clean_path()) + elif applet_style.is_remote(): + rsc_path = applet_style.raw_uri + + if rsc_path is not None: + applet_style_html += f"" return applet_style_html @@ -26,16 +50,41 @@ def render_applet_scripts(applet_data: ContentApplet, is_standalone: bool = Fals applet_script_html = "" for applet_script in applet_data.resources.scripts: + rsc_path = None + if is_standalone: - with open(os.path.join("./static/resources/NibblePoker/applets/", applet_data.id, applet_script)) as applet_script_file: - applet_script_html += "" if applet_script.endswith(".mjs") else ">") - applet_script_html += applet_script_file.read() - applet_script_html += "" + if not applet_script.can_be_standalone(): + continue + + if applet_script.is_applet(): + rsc_path = os.path.join( + "./static/resources/NibblePoker/applets/", + applet_data.id, + applet_script.get_clean_path()) + elif applet_script.is_standalone(): + rsc_path = os.path.join( + "./static/resources/Standalone/", + applet_script.get_clean_path()) + + if rsc_path is not None: + with open(rsc_path) as applet_script_file: + applet_script_html += "" if applet_script.raw_uri.endswith(".mjs") else ">") + applet_script_html += applet_script_file.read() + applet_script_html += "" + else: - applet_script_html += ("") + if applet_script.is_applet(): + rsc_path = url_for( + "static", + filename="/resources/NibblePoker/applets/" + + applet_data.id + "/" + + applet_script.get_clean_path()) + elif applet_script.is_remote(): + rsc_path = applet_script.raw_uri + + if rsc_path is not None: + applet_script_html += f"" return applet_script_html